-3

可能重复:
检查列表是否已包含项目?

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 再次存在,所以这次我不想处理它来执行递归,如果它会再次执行相同的操作。我需要以某种方式制作或检查它是否会执行每个链接一次。我怎样才能检查它?

我不需要检查该项目是否已经存在于列表中我需要检查它是否已经存在所以不要再这样做了,因为它会再次挖掘相同的链接并自我重复。

4

5 回答 5

8

不要为此使用列表 - 使用 a Hashset<string>- 这期望 O(1) 查找时间而不是 O(n) 用于列表,并且真的“集合”隐喻非常适合:

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哈希集的声明必须在方法之外,例如让它成为一个成员变量,这样你就可以维护访问过的页面的历史。

于 2012-05-14T18:23:12.593 回答
4

我猜你需要List.Contains方法,但是

List.Contains 是 O(n),我建议使用具有 O(1) 查找的 Hashset。

如果您的列表包含所有条目,那么您还可以使用 Linq 中的 Distinct() 函数,它将返回一个仅包含 Distinct 元素的枚举。

webSites.Distinct()
于 2012-05-14T18:22:32.367 回答
1

将访问过的项目保存在HashSet<string>.

Add在访问页面以及Contains检查您是否已经访问过该页面时使用。

于 2012-05-14T18:22:58.537 回答
0

创建一个临时列表并将其命名为“temp”。for 循环的每次迭代,查看 webSites 中该位置的字符串是否已经在 temp 中。如果是,请忽略它。如果不是,请将其添加到 temp 然后处理它。

编辑:显然这不是最好的方法。

于 2012-05-14T18:23:30.493 回答
0

为什么不首先选择不同的网站列表?

foreach (var site in webSites.GroupBy(s => s))
{
  webCrawler(t, levels - 1);
  // csFiles.add
}
MessageBox.Show(webSites.Count().ToString());
return csFiles;
于 2012-05-14T18:33:54.707 回答