41

我的 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_string);
}

正如您可以想象的那样,这适用于数百个条目。但是我面临着生成数百万个字符串的情况。并且随着每个添加的字符串检查重复项变得越来越慢。

有没有更快的方法来避免重复?

4

7 回答 7

59

使用可以更有效地确定项目是否存在的数据结构,即HashSet. 它可以在恒定时间内确定一个项目是否在集合中,而不管集合中有多少项目。

如果您确实需要 a 中的项目List,或者您需要结果列表中的项目按照它们生成的顺序排列,那么您可以将数据存储在列表和哈希集中;如果该项目当前不存在于HashSet.

于 2013-06-24T14:59:10.527 回答
13

最简单的方法是使用这个:

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();

当然,如果您不需要按索引访问项目,您可以通过删除ToList和仅使用IEnumerable.

于 2013-06-24T14:59:10.543 回答
11

不要使用List<>. 使用Dictionary<>orHashSet<>代替!

于 2013-06-24T14:59:30.630 回答
9

HashSet<string>如果顺序不重要,您可以使用:

HashSet<string> myHashSet = new HashSet<string>();
for (int i = 0; i < total; i++) 
{
   string random_string = GetRandomString(pattern);
   myHashSet.Add(random_string);
}

HashSet 类提供高性能的集合操作。集合是不包含重复元素且其元素没有特定顺序的集合。

MSDN

或者如果顺序重要,我建议使用SortedSet(仅限 .net 4.5)

于 2013-06-24T15:01:16.227 回答
2

不是一个好方法,而是一种快速修复,使用布尔值检查整个列表中是否有任何重复条目。

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;
     }

    }
于 2017-11-26T12:10:36.573 回答
0

你有没有尝试过:

myList = myList.Distinct()
于 2013-06-24T15:00:59.590 回答
0

Hashtable 将是一种比列表更快的方法来检查项目是否存在。

于 2013-06-24T14:58:49.720 回答