2 つの文字列を取り、両方に共通する文字数を返すメソッドを探しています。
「G010」と「G1820A」は、G、0、および 1 文字が両方に存在するため、3 を返す必要があります。
char が両方に 2 回存在する場合は、次のように別々にカウントする必要があります。
"G12AA" & "GAA2" は、G、A、A、および 2 文字が両方に存在するため、4 を返す必要があります。
これについて何か助けはありますか?これまでのところ、Google 検索はあまり役に立ちませんでした。
2 つの文字列を取り、両方に共通する文字数を返すメソッドを探しています。
「G010」と「G1820A」は、G、0、および 1 文字が両方に存在するため、3 を返す必要があります。
char が両方に 2 回存在する場合は、次のように別々にカウントする必要があります。
"G12AA" & "GAA2" は、G、A、A、および 2 文字が両方に存在するため、4 を返す必要があります。
これについて何か助けはありますか?これまでのところ、Google 検索はあまり役に立ちませんでした。
さて、これはどうでしょうか。遅延評価を最大化し、文字列操作を最小化するという利点があります。
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();
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);
これは、入れ子ループを行わず、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;
}
次のコードを確認してください --> src が最初の文字列で、chk が 2 番目の文字列です
変数カウント = 0;変数 i=0; src.ToList().ForEach((x)=> {
while(chk.Substring(i).IndexOf(x) >= 0) {
count++; i++; if( i > chk.Length) break; }
});