【问题标题】:Extracting unique and non-unique strings to separate output files提取唯一和非唯一字符串以分隔输出文件
【发布时间】:2014-12-23 16:04:20
【问题描述】:

我在尝试仅从测试文件中提取不重复的行和仅重复的行时遇到问题。输入文件包含重复行和非重复行。

我创建了一个日志记录函数,我可以将所有唯一的行从中提取到一个单独的文件中,但其中包括重复的行和不重复的行,我需要将它们分开。

这是我目前所拥有的;

static void Dupes(string path1, string path2)
{
    string log = log.txt;
    var sr = new StreamReader(File.OpenRead(path1));
    var sw = new StreamWriter(File.OpenWrite(path2));
    var lines = new HashSet<int>();
    while (!sr.EndOfStream)
    {
        string line = sr.ReadLine();
        int hc = line.GetHashCode();
        if (lines.Contains(hc))

            continue;

        lines.Add(hc);
        sw.WriteLine(line);

    }
    sw.Close();
}

理想情况下,这将包含在两个函数中,因此可以调用它们来对输出内容执行不同的操作。

【问题讨论】:

  • 有什么原因不能先将所有行读入内存?
  • 输入文件有多大?
  • @Steve 的问题是相关的。如果您可以将文件加载到内存中,Joney 的响应非常好。如果您有内存大小问题,那么您使用散列的想法很好,但可能导致散列冲突是不好的(也许另一种具有更大输出大小的散列算法更可取)。但要实现它,您必须读取文件两次,首先构建一个从“行哈希”到“行数”的字典。在第二次您重新阅读文件并使用字典来了解每行是否存在 1 次或多次。

标签: c# string unique


【解决方案1】:

使用 LINQ 对项目进行分组,然后检查计数:

var lines = File.ReadAllLines(path1);

var distincts = lines.GroupBy(l => l)
                    .Where(l => l.Count() == 1)
                    .Select(l => l.Key)
                    .ToList();

var dupes = lines.Except(distincts).ToList();

值得注意的是Except 不会返回重复项——这是我刚刚学到的。所以以后不用再打电话给Distinct了。

【讨论】:

    【解决方案2】:

    你可以这样做

    var lines = File.ReadAllLines(path1);
    
    var countLines = lines.Select(d => new
    {
        Line = d,
        Count = lines.Count(f => f == d),
    });
    
    var UniqueLines = countLines.Where(d => d.Count == 1).Select(d => d.Line);
    var NotUniqueLines = countLines.Where(d => d.Count > 1).Select(d => d.Line);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-13
      • 2023-03-12
      • 2023-03-27
      • 1970-01-01
      • 2023-03-22
      • 2018-11-16
      • 2023-03-08
      • 2011-01-12
      相关资源
      最近更新 更多