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应该被返回。绝对同意,我急于提供帮助是无济于事的。我知道已经有答案了,但我不太清楚,我对速度很好奇。修正错误