1

我有以下两种方法。方法 1 使用 aHashSet和 List。第二种方法使用Sorting of Array.

哪个更好processing speed

  1. 什么时候有很多记录?
  2. 当有少量记录时?

代码

        string entryValue = "A,B, a , b, ";

        if (!String.IsNullOrEmpty(entryValue.Trim()))
        {

            //APPROACH 1
            bool isUnique = true;

            //Hash set is unique set  -- Case sensitivty Ignored
            HashSet<string> uniqueRecipientsSet = new HashSet<string>(entryValue.Trim().Split(',').Select(t => t.Trim()),StringComparer.OrdinalIgnoreCase );

            //List can hold duplicates
            List<string> completeItems = new List<string>(entryValue.Trim().Split(',').Select(t => t.Trim()));

            if (completeItems.Count != uniqueRecipientsSet.Count)
            {
                isUnique = false;
            }


            //APPROACH 2
            bool isUniqueCheck2 = true;
            string[] words = entryValue.Split(',');
            Array.Sort(words);

            for (int i = 1; i < words.Length; i++)
            {
                if (words[i].ToLower().Trim() == words[i - 1].ToLower().Trim())
                {
                    isUniqueCheck2 = false;
                    break;
                }
            }


            bool result1 = isUnique;
            bool result2 = isUniqueCheck2;


        }

参考:

  1. 拆分逗号分隔的字符串以计算重复项
  2. MSDN 博客 - 使用 LINQ 查找重复项
4

3 回答 3

1

哈希集方法是 O(n);排序方法是 O(n log n)。

但是,一个更快的选择是通过在您第一次看到重复项时立即停止来缩短哈希集方法:

HashSet<string> uniqueRecipientsSet
    = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
bool isUnique = true;

foreach(var item in entryValue.Split(',').Select(t => t.Trim()))
{
    if (!uniqueRecipientsSet.Add(item))
    {
        isUnique = false;
        break;
    }
}

可以在 LINQ 中隐藏foreach循环:

HashSet<string> uniqueRecipientsSet
    = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
bool isUnique = entryValue.Split(',').Select(t => t.Trim())
    .All(i => uniqueRecipientsSet.Add(i));

这是“带有副作用的 LINQ”,但它确实将整个事情减少到两行。

您可以编写自己的AreAllDistinct扩展方法来避免副作用:

public static bool AreAllDistinct<T>(
    this IEnumerable<T> source, IEqualityComparer<T> comparer)
{
    HashSet<T> checker = new HashSet<T>(comparer);
    foreach (var t in T)
        if (!checker.Add(t))
            return false;
    return true;
}

bool isUnique = entryValue.Split(',').Select(t => t.Trim())
    .AreAllDistinct(StringComparer.OrdinalIgnoreCase);
于 2012-12-12T11:59:40.607 回答
1

您可以简化您的第一种方法:

List<string> completeItems = new List<string>(entryValue.Trim().Split(',').Select(t => t.Trim()));
isUnique = completeItems.Count == completeItems.Distinct().Count();

这将消除多次拆分,并将哈希集隐藏在Distinct(). 请注意,该if语句也是不必要的。

于 2012-12-12T11:58:44.120 回答
1

你本可以使用StopWatch自己。第一种方法要快一点:

1) 00:00:00.0460701  2) 00:00:00.0628364

每次逼近 10000 次重复(只是测量时间的简单方法)

于 2012-12-12T12:02:28.197 回答