私はこのコードを持っています:
private void removeDuplicates(List<string> currentSites, List<string> visitedSites)
{
for (int i = 0; i < currentSites.Count; i++)
{
for (int x = 0; x < visitedSites.Count; x++)
{
}
}
}
私は2つのリストを取得しており、最初に1つのリストの各アイテムを他のリストのアイテムと比較して、他のリストのすべてのアイテムをループして比較する必要があります。項目の 1 つが他のリストに存在する場合は、それを NULL としてマークします。
VisitedSites が currentSites にあることを確認して、1 つのアイテムをすべてのリストに移動し、null としてマークするかどうかを確認する必要があります。
いずれにせよ、2 つのループの 1 つをもう 1 つ使用する必要があります。
nullを見つけてnullをマークし、その後ブレークします。
次に、別のループ FOR を追加して、間違っていなければ List currentSites を移動し、マークされた NULL 項目をすべて削除する必要があります。
アイデアは、重複したアイテムをnullとしてマークしてリストを比較し、次にすべてのnullを削除することです。
これは最初からのコードです:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Net;
using System.Web;
namespace GatherLinks
{
public partial class Form1 : Form
{
List<string> currentCrawlingSite;
List<string> sitesToCrawl;
int actual_sites;
BackgroundWorker worker;
int sites = 0;
int y = 0;
string guys = "http://www.google.com";
public Form1()
{
InitializeComponent();
currentCrawlingSite = new List<string>();
sitesToCrawl = new List<string>();
actual_sites = 0;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private List<string> getLinks(HtmlAgilityPack.HtmlDocument document)
{
List<string> mainLinks = new List<string>();
var linkNodes = document.DocumentNode.SelectNodes("//a[@href]");
if (linkNodes != null)
{
foreach (HtmlNode link in linkNodes)
{
var href = link.Attributes["href"].Value;
mainLinks.Add(href);
}
}
return mainLinks;
}
private List<string> webCrawler(string url, int levels , DoWorkEventArgs eve)
{
HtmlAgilityPack.HtmlDocument doc;
HtmlWeb hw = new HtmlWeb();
List<string> webSites;// = new List<string>();
List<string> csFiles = new List<string>();
csFiles.Add("temp string to know that something is happening in level = " + levels.ToString());
csFiles.Add("current site name in this level is : " + url);
try
{
doc = hw.Load(url);
currentCrawlingSite.Add(url);
webSites = getLinks(doc);
removeDuplicates(currentCrawlingSite, webSites);
removeDuplicates(currentCrawlingSite, sitesToCrawl);
sitesToCrawl = webSites;
if (levels == 0)
{
return csFiles;
}
else
{
for (int i = 0; i < webSites.Count() && i < 20; i++) {
int mx = Math.Min(webSites.Count(), 20);
if ((worker.CancellationPending == true))
{
eve.Cancel = true;
break;
}
else
{
string t = webSites[i];
if ((t.StartsWith("http://") == true) || (t.StartsWith("https://") == true))
{
actual_sites++;
csFiles.AddRange(webCrawler(t, levels - 1,eve));
this.Invoke(new MethodInvoker(delegate { Texts(richTextBox1, "Level Number " + levels + " " + t + Environment.NewLine, Color.Red); }));
worker.ReportProgress(Math.Min((int)((double)i / mx * 100),100));
}
}
}
return csFiles;
}
}
catch
{
return csFiles;
}
}
したがって、removeDuplicated 関数を 2 回呼び出すには、removeDuplicated で上に書いたことを行う必要があります。または、何らかの方法で webSites のリンクを sitesToCrawl に追加します。アイデアは、csFiles リストに追加するときに重複する項目がないように webSites をループするときです。