C# 删除列表中包含其他名称的名称

C# 删除列表中包含其他名称的名称,c#,list,duplicates,C#,List,Duplicates,我有一个文件,每行都有“Name | Number”,我希望删除列表中包含其他名称的行。 例如,如果文件中有“PEDRO|3”、“PEDROFILHO|5”、“PEDROPHELIS|1”,我希望删除行“PEDROFILHO|5”、“PEDROPHELIS|1”。 这个列表有180万行,我是这样做的,但是太慢了: List<string> names = File.ReadAllLines("firstNames.txt").ToList(); List<string>

我有一个文件,每行都有
“Name | Number”
,我希望删除列表中包含其他名称的行。 例如,如果文件中有
“PEDRO|3”、“PEDROFILHO|5”、“PEDROPHELIS|1”,我希望删除行“PEDROFILHO|5”、“PEDROPHELIS|1”。

这个列表有180万行,我是这样做的,但是太慢了:

List<string> names = File.ReadAllLines("firstNames.txt").ToList();
List<string> result = File.ReadAllLines("firstNames.txt").ToList();

foreach (string name in names)
{
    string tempName = name.Split('|')[0];
    List<string> temp = names.Where(t => t.Contains(tempName)).ToList();
    foreach (string str in temp)
    {
        if (str.Equals(name))
        {
            continue;
        }
        result.Remove(str);
    }
}
File.WriteAllLines("result.txt",result);
List name=File.ReadAllLines(“firstNames.txt”).ToList();
列表结果=File.ReadAllLines(“firstNames.txt”).ToList();
foreach(名称中的字符串名称)
{
字符串tempName=name.Split(“|”)[0];
List temp=names.Where(t=>t.Contains(tempName)).ToList();
foreach(临时字符串str)
{
如果(str.Equals(name))
{
继续;
}
结果:去除(str);
}
}
writeAllines文件(“result.txt”,result);

有人知道更快的方法吗?或者如何提高速度?

由于您要查找单词中的所有匹配项,因此最终将使用O(n2)算法。您可以稍微改进实现,以避免在列表中删除字符串,这本身就是一个O(n)操作:

var toDelete = new HashSet<string>();
var names = File.ReadAllLines("firstNames.txt");
foreach (string name in names) {
    var tempName = name.Split('|')[0];
    toDelete.UnionWith(
        // Length constraint removes self-matches
        names.Where(t => t.Length > name.Length && t.Contains(tempName))
    );
}
File.WriteAllLines("result.txt", names.Where(name => !toDelete.Contains(name)));
var toDelete=newhashset();
var names=File.ReadAllLines(“firstNames.txt”);
foreach(名称中的字符串名称){
var tempName=name.Split(“|”)[0];
托德莱特(
//长度约束删除自匹配项
name.Where(t=>t.Length>name.Length&&t.Contains(tempName))
);
}
File.writeAllines(“result.txt”,names.Where(name=>!toDelete.Contains(name));

这种方法有效,但我不知道是否更快。我还没有测试过数百万行。如果名称的大小写相同,请删除tolower

        List<string> names = File.ReadAllLines(@"C:\Users\Rob\Desktop\File.txt").ToList();

        var result = names.Where(w => !names.Any(a=> w.Split('|')[0].Length> a.Split('|')[0].Length  &&  w.Split('|')[0].ToLower().Contains(a.Split('|')[0].ToLower())));

        File.WriteAllLines(@"C:\Users\Rob\Desktop\result.txt", result);
List name=File.ReadAllLines(@“C:\Users\Rob\Desktop\File.txt”).ToList();
var result=names.Where(w=>!names.Any(a=>w.Split(“|”)[0]。Length>a.Split(“|”)[0]。Length&&w.Split(“|”)[0]。ToLower()。包含(a.Split(“|”)[0]。ToLower());
writeAllines(@“C:\Users\Rob\Desktop\result.txt”,result);
测试文件

罗布| 1 罗比| 2 伯特| 3 罗伯特| 4 1月5日 约翰| 6 珍妮丝| 7 卡罗尔| 8 卡罗琳| 9 杰夫| 10 杰弗里| 11

结果

罗布| 1 伯特| 3 1月5日 约翰| 6 卡罗尔| 8
Geoff | 10

您是否也要删除
“DELPEDRO | 5”
,还是只查找前缀匹配?如果删除,则列表中包含其他名称的任何名称都将被删除。使用类似于排序的方法,甚至只对列表排序并进行二进制搜索,可以更快地完成前缀匹配。根据清除的数量,首先清除所有前缀匹配可能会更快,然后进行“包含”检查。在这种情况下,John和Bert应该被返回。绝对同意,我急于提供帮助是无济于事的。我知道已经有答案了,但我不太清楚,我对速度很好奇。修正错误