如何循环并比较两个文本文件中的数百万个值?

May*_*hav 2 c# arrays performance loops data-structures

我有两个文本文件文件(TXT),其中包含超过200万个不同的文件名.我想遍历第一个文件中的所有名称,并找到第二个文本文件中也存在的名称.

我试过循环,StreamReader但需要花费很多时间.我也尝试了下面的代码,但它仍然需要太多时间.

StreamReader first = new StreamReader(path);
string strFirst = first.ReadToEnd();
string[] strarrFirst = strFirst.Split('\n');

 bool found = false;

StreamReader second = new StreamReader(path2);
string str = second.ReadToEnd();
string[] strarrSecond = str.Split('\n');

for (int j = 0; j < (strarrFirst.Length); j++)
{
          found = false;

    for (int i = 0; i < (strarrSecond .Length); i++)
    {
        if (strarrFirst[j] == strarrSecond[i])
        {
            found = true;
            break;
        }
    }

    if (!found)
    {
        Console.WriteLine(strarrFirst[j]);
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么比较文件的好方法?

Jon*_*eet 10

这个怎么样:

var commonNames = File.ReadLines(path).Intersect(File.ReadLines(path2));
Run Code Online (Sandbox Code Playgroud)

这是O(N + M)代替,测试你目前的解决方案每天在第一档用行每一第二档线- O(N*M).

这是假设您使用的是.NET 4.否则,您可以使用File.ReadAllLines,但这会将整个文件读入内存.或者你可以写出相当于File.ReadLines自己的东西 - 这并不是非常难.

最终,当你摆脱当前代码中的O(N*M)问题时,你可能会被文件IO限制 - 没有太多方法可以解决这个问题.

编辑:对于.NET 2,首先让我们实现类似的东西ReadLines:

public static IEnumerable<string> ReadLines(string file)
{
    using (TextReader reader = File.OpenText(file))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们真的想要使用a HashSet<T>,但这不是在.NET 2中 - 所以让我们使用Dictionary<TKey, TValue>:

Dictionary<string, string> map = new Dictionary<string, string>();
foreach (string line in ReadLines(path))
{
    map[line] = line;
}

List<string> intersection = new List<string>();
foreach (string line in ReadLines(path2))
{
    if (map.ContainsKey(line))
    {
        intersection.Add(line);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @CPX:涉及两个文件 - 你拿N的大小?这就是我使用N和M的原因,每个文件都有一个. (2认同)