-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;

私が持っているwebSitesで言うことができます:

www.google.com

www.microsoft.com

今度は第2レベルで、www.google.comが再び存在するとしましょう。そのため、今回は、同じことを繰り返し実行するのであれば、リクルートを実行するために処理したくありません。どういうわけか、各リンクを1回実行するかどうかを確認する必要があります。どうすれば確認できますか?

アイテムがリストにすでに存在するかどうかを確認する必要はありません。アイテムがすでに存在するかどうかを確認する必要があります。同じリンクを再度掘り下げて繰り返すので、もう一度確認する必要はありません。

4

5 に答える 5

8

これにはリストを使用しないでください-使用してくださいHashset<string>-これはリストのO(n)ではなくO(1)ルックアップ時間を期待しており、実際には「セット」メタファーは完全に適合します。

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)ルックアップを持つハッシュセットをお勧めします。

リストにすべてのエントリが含まれている場合は、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に追加してから、処理します。

編集:どうやらこれは最善のアプローチではありません。

于 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 に答える