9

2 つの文字列を取り、両方に共通する文字数を返すメソッドを探しています。

「G010」と「G1820A」は、G、0、および 1 文字が両方に存在するため、3 を返す必要があります。

char が両方に 2 回存在する場合は、次のように別々にカウントする必要があります。

"G12AA" & "GAA2" は、G、A、A、および 2 文字が両方に存在するため、4 を返す必要があります。

これについて何か助けはありますか?これまでのところ、Google 検索はあまり役に立ちませんでした。

4

9 に答える 9

7

さて、これはどうでしょうか。遅延評価を最大化し、文字列操作を最小化するという利点があります。

public int CommonChars(string left, string right)
{
    return left.GroupBy(c => c)
        .Join(
            right.GroupBy(c => c),
            g => g.Key,
            g => g.Key,
            (lg, rg) => lg.Zip(rg, (l, r) => l).Count())
        .Sum(); 
}

基本的に、各辺を文字でグループ化し、両側にグループを持つ文字を見つけます。一致したグループは、いずれかがなくなるまで、タンデムにカウントされます。これらのカウントが合計されて結果が生成されます。


これを任意の 2 つのシーケンスに対して一般的に実行するのは簡単です。下記参照、

public static int CommomCount<T>(
        this IEnumerable<T> source,
        IEnumerable<T> sequence,
        IEqualityComparer<T> comparer = null)
{
    if (sequence == null)
    {
        return 0;
    }

    if (comparer == null)
    {
        comparer = EqualityComparer<T>.Default;
    }

    return source.GroupBy(t => t, comparer)
        .Join(
            sequence.GroupBy(t => t, comparer),
            g => g.Key,
            g => g.Key,
            (lg, rg) => lg.Zip(rg, (l, r) => l).Count(),
            comparer)
        .Sum();
}

このように使用します。

"G12AA".CommonCount("GAA2")

オプションのcomparerパラメーターは、大文字と小文字を区別しない、またはその他の特別な処理が必要な場合に役立ちます。


Sum()再利用可能性のために、次のように、 を削除してを返しIEnumerable<T>、呼び出しに合計を追加したくなるでしょう。

public static IEnumerable<T> Commom<T>(
        this IEnumerable<T> source,
        IEnumerable<T> sequence,
        IEqualityComparer<T> comparer = null)
{
    if (sequence == null)
    {
        return Enumerable.Empty<T>();
    }

    if (comparer == null)
    {
        comparer = EqualityComparer<T>.Default;
    }

    return source.GroupBy(t => t, comparer)
        .Join(
            sequence.GroupBy(t => t, comparer),
            g => g.Key,
            g => g.Key,
            (lg, rg) => lg.Zip(rg, (l, r) => l),
            comparer)
        .SelectMany(g => g);
}

簡単にできるように

Console.WriteLine(new string("G12AA".Common("GAA2").ToArray()));

または単にオリジナル

"G12AA".Common("GAA2").Count();
于 2014-02-13T10:47:29.250 に答える
1
        string s1 = "G12A";
        string s2 = "GAA2";
        List<char> lst1 = s1.ToList();
        List<char> lst2 = s2.ToList();
        int count = 0;
        foreach (char c in lst2)
        {
            if (lst1.Contains(c))
            {
                lst1.Remove(c);
                count++;
            }
        }
        Console.WriteLine(count);
于 2014-02-13T09:38:29.220 に答える
0

これは、入れ子ループを行わず、Dictionary を使用したハッシュ検索に依存するため、より大きな入力でより高速に実行されます。一方で、より多くのメモリを使用します。

 public int CommonCharacterCount(string s1, string s2)
            { 
                var r=0;
                Dictionary<char,int> s2Dict = new Dictionary<char,int>();
                foreach (var ch in s2)
                {
                    if (s2Dict.ContainsKey(ch))
                        s2Dict[ch] = s2Dict[ch]+1;
                    else s2Dict.Add(ch,1);
                }

                foreach (var c in s1)
                {
                    if (s2Dict.ContainsKey(c) && s2Dict[c]>0)
                    {
                        r++;
                        s2Dict[c] = s2Dict[c] - 1;
                    }
                }
                return r;
            }
于 2014-02-13T09:53:23.427 に答える
-3

次のコードを確認してください --> src が最初の文字列で、chk が 2 番目の文字列です

変数カウント = 0;変数 i=0; src.ToList().ForEach((x)=> {
while(chk.Substring(i).IndexOf(x) >= 0) {
count++; i++; if( i > chk.Length) break; }
});

于 2014-02-13T09:06:54.733 に答える