C# 避免列表中重复的快速方法<&燃气轮机;在C中#
我的C#程序根据给定的模式生成随机字符串。这些字符串存储在列表中。由于不允许复制,我这样做:C# 避免列表中重复的快速方法<&燃气轮机;在C中#,c#,list,duplicates,C#,List,Duplicates,我的C#程序根据给定的模式生成随机字符串。这些字符串存储在列表中。由于不允许复制,我这样做: List<string> myList = new List<string>(); for (int i = 0; i < total; i++) { string random_string = GetRandomString(pattern); if (!myList.Contains(random_string)) myList.Add(random_stri
List<string> myList = new List<string>();
for (int i = 0; i < total; i++) {
string random_string = GetRandomString(pattern);
if (!myList.Contains(random_string)) myList.Add(random_string);
}
List myList=new List();
对于(int i=0;i
正如您所想象的,这可以很好地处理数百个条目。但我面临着生成数百万字符串的情况。随着每个字符串的增加,检查重复项的速度越来越慢
有没有更快的方法来避免重复?哈希表是检查项目是否存在的一种比列表更快的方法。使用可以更有效地确定项目是否存在的数据结构,即
哈希集。无论集合中的项目数量如何,它都可以在固定时间内确定集合中是否有项目
如果您确实需要列表中的项目
,或者需要结果列表中的项目按生成顺序排列,则可以将数据存储在列表和哈希集中;如果该项当前不存在于哈希集中,则将其添加到两个集合中最简单的方法是:
myList = myList.Distinct().ToList();
尽管这需要创建一次列表,然后创建一个新列表。更好的方法可能是提前制作发电机:
public IEnumerable<string> GetRandomStrings(int total, string pattern)
{
for (int i = 0; i < total; i++)
{
yield return GetRandomString(pattern);
}
}
...
myList = GetRandomStrings(total, pattern).Distinct().ToList();
public IEnumerable GetRandomString(整数合计,字符串模式)
{
对于(int i=0;i
当然,如果您不需要按索引访问项目,您可以通过删除ToList
和只使用IEnumerable
不使用列表来提高效率。改用字典
或哈希集
您是否尝试过:
myList = myList.Distinct()
如果顺序不重要,您可以使用HashSet
:
HashSet<string> myHashSet = new HashSet<string>();
for (int i = 0; i < total; i++)
{
string random_string = GetRandomString(pattern);
myHashSet.Add(random_string);
}
HashSet myHashSet=newhashset();
对于(int i=0;i
HashSet类提供高性能的set操作。集合是不包含重复元素的集合,其元素没有特定顺序
或者,如果订单很重要,我建议使用(.net 4.5 only)不是一种好方法,而是一种快速修复方法,
用bool检查整个列表中是否有重复条目
bool containsKey;
string newKey;
public void addKey(string newKey){
foreach(string key in MyKeys){
if(key == newKey){
containsKey = true;
}
}
if(!containsKey){
MyKeys.add(newKey);
}else{
containsKey = false;
}
}
将它们全部添加,然后使用Distinct()检查重复项,然后再将删除的数字添加回去,这样会更快吗?@Jonesy:这听起来像是值得对特定数据集进行测试的东西。如果它的速度确实更快,那么我们可以将性能优化与它添加到代码中的模糊处理进行权衡(在本例中并不多)。@David我可能会从理论上论证说,HashSet
会更快,因为最初对内存的影响较小,之后不需要完全迭代。检查每个项目的成本仍然存在,但该数据结构已经过优化。@Robert您能为每个文档使用GUID
吗?@musefan甚至进行一次数据库查询来确定数据库中是否已经存在一个项目,这将花费数十万以上的时间,如果不是,则进行数百万次检查,以查看某个项是否存在于内存中的哈希集中。使用DB来解决这个特殊问题很容易会导致数千倍的速度下降。在我看来,使用.Distinct
删除列表中的数百万个字符串并没有那么有效。@DarrenDavies内部,Distinct
使用哈希集,正如其他人所建议的那样。唯一低效的部分是首先生成列表,然后使用distinct,我在回答的第二部分中已经提到了这一点。@p.s.w.g我假设您的GetRandomStrings
方法的目的是产生字符串,而不仅仅是将其设置为本地字符串,然后将其丢弃。另外,如果结果中需要一定数量的字符串,那么让GetRandomStrings
生成一个无限长的序列,然后使用Take
将其限制在所需的大小可能是有意义的。然后,您可以将Take
放在Distinct
之前或之后,具体取决于您是要指定生成的字符串数还是要指定生成的唯一字符串数。@Servy我最初是这样实现的,但无限生成器可能很危险,他没有键/值关系,只有一串字符串,所以他需要的是一个集合而不是一个映射。此外,哈希表不是通用的;如果确实需要映射结构,则应该使用通用的字典。您不应该在非遗留代码中使用哈希表。请注意,SortedSet
对元素进行排序。如果需要一个有序集(即保持元素顺序)OrderedDictionary
将是一个更好的选择。缺点是它不是泛型的。那么如何获取哈希对象呢?HashSet没有GET,也没有实现self的有效性。好的,所以我使用了HashSet
,速度提高了很多。然而,我确实有一个新问题。我需要散列集中有一定数量的条目。如果我在我的问题中使用for-for循环,那么它在2000000次循环后停止。哈希集中不存在重复项,但如果命中重复项,哈希集中没有2000000个条目。我怎么能避免呢<代码>如果(myList.Count<2000000)myList.Add(随机_字符串)代码>可以防止这种情况发生,但又有点慢。@Robert不用for(int i=0;i
只需使用for(int i=0;set.Count
。或者,如果您实际上根本不需要i
,那么只需while(se