如果不知道GetLinks()的作用,很難讓代碼更好。無論如何,這避免了遞歸。標準習慣用法是,當你列舉它時不要改變集合。雖然運行時可以讓你這樣做,但推理是它是錯誤的來源,所以最好創建一個新的集合或者自己控制迭代。
- 創建一個包含所有網址的隊列。
- 當出現隊列時,我們幾乎可以說我們已經處理了它,因此將其添加到結果中。
- 如果GetLinks()返回任何內容,則將它們添加到隊列中並處理它們。
。
public List<string> ExpandLinksOrSomething(List<string> urls)
{
List<string> result = new List<string>();
Queue<string> queue = new Queue<string>(urls);
while (queue.Any())
{
string url = queue.Dequeue();
result.Add(url);
foreach(string newResult in GetLinks(url))
{
queue.Enqueue(newResult);
}
}
return result;
}
天真的實現假定GetLinks()
不會返回循環引用。例如A復原B,和B返回A.這可以通過固定:
List<string> newItems = GetLinks(url).Except(result).ToList();
foreach(string newResult in newItems)
{
queue.Enqueue(newResult);
}
*正如其他人指出,使用字典可能取決於你有多少項目過程中更有效率。
我覺得奇怪的是,GetLinks()會返回一個值,然後再解析到更多Url的。也許你想要做的只是一級擴展。如果是這樣,我們可以完全擺脫隊列。
public static List<string> StraightProcess(List<string> urls)
{
List<string> result = new List<string>();
foreach (string url in urls)
{
result.Add(url);
result.AddRange(GetLinks(url));
}
return result;
}
我決定重寫它,因爲雖然其他答案使用隊列,但並不明顯他們沒有永遠運行。
你想蜘蛛整個互聯網或只是得到原來的列表中的網頁上的鏈接? – 2008-11-13 15:27:34
呵呵,這只是一個例子,當然:) – 2008-11-13 15:28:55
蜘蛛互聯網是有趣的;我開始一個過程,以蜘蛛www.altavista.com一次有趣,當我的硬盤滿了,我發現它主要是pr0n :) – configurator 2008-11-13 15:50:14