for (int i = 0; i < webSites.Count(); i++)
{
string t = webSites[i];
webCrawler(t, levels - 1);
// csFiles.add
}
MessageBox.Show(webSites.Count().ToString());
return csFiles;
让我们在网站上说:
www.google.com
www.microsoft.com
现在在第二级让我们说www.google.com再次存在,所以这次我不想处理它来做recrusive如果它会再次做同样的事情。我需要以某种方式制作或检查它是否会执行每个链接一次。我怎么检查呢?
我不需要检查列表中是否已经存在该项目我需要检查它是否已经存在,所以不要再这样做,因为它会再次挖掘相同的链接并重复自己。
答案 0 :(得分:8)
不要使用列表 - 使用Hashset<string>
- 对于列表,这预期O(1)查找时间而不是O(n),并且“set”隐喻真的完全适合: / p>
HashSet<string> visitedPages = new HashSet<string>();
for (int i = 0; i < webSites.Count(); i++)
{
string page = webSites[i];
if(visitedPages.Add(page)) //returns true if new page was added
{
webCrawler(page, levels - 1);
}
}
如果以递归方式调用此方法,当然visitedPages
哈希集的声明必须在方法之外,例如使其成为成员变量,以便您可以维护被访问页面的历史记录。
答案 1 :(得分:4)
List.Contains方法,但
List.Contains是O(n),我会推荐一个Hashset,它有一个O(1)查找..
如果你的列表包含所有条目,那么你也可以使用Linq中的Distinct()函数,它将返回一个只包含Distinct元素的枚举。
webSites.Distinct()
答案 2 :(得分:1)
将访问过的项目保存在HashSet<string>
。
在访问网页时使用Add
,在检查您是否已访问过该网页时使用Contains
。
答案 3 :(得分:0)
创建一个临时列表并调用它,比方说,“temp”。 for循环的每次迭代,看看webSites中该位置的字符串是否已经处于临时状态。如果是,请忽略它。如果不是,请将其添加到temp,然后进行处理。
编辑:显然这不是最好的方法。答案 4 :(得分:0)
为什么不首先选择不同的网站列表?
foreach (var site in webSites.GroupBy(s => s))
{
webCrawler(t, levels - 1);
// csFiles.add
}
MessageBox.Show(webSites.Count().ToString());
return csFiles;