1

私は次の2つのアプローチがあります。アプローチ1はとHashSetリストを使用します。2番目のアプローチはを使用し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

最初のアプローチを単純化できます。

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

ハッシュセットアプローチは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」ですが、全体を2行に減らします

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

あなたはStopWatch自分自身を使うことができたでしょう。最初のアプローチは少し高速です。

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

各アプローチは10000回の繰り返し(時間を測定するための簡単な方法)

于 2012-12-12T12:02:28.197 に答える