あなたはそれをやっている間、最も簡単な方法は、(それは、対応する文字をmatces)を同時に手動で両方の文字列を歩くと辞書を構築することが考えられます:
if(input1.Length != input2.Length)
return false;
var characterMap = new Dictionary<char, char>();
for(int i = 0; i < input1.Length; i++)
{
char char1 = input1[i];
char char2 = input2[i];
if(!characterMap.ContainsKey(char1))
{
if (characterMap.ContainsValue(char2))
return false;
characterMap[char1] = char2;
}
else
{
if(char2 != characterMap[char1])
return false;
}
}
return true;
あなたが構築することができ、同様に正規表現これは確かに1回の比較では効率的ではありませんが、将来、複数の文字列に対して1つの繰り返しパターンをチェックしたい場合に役立ちます。今回は、文字を後の参照に関連付けます。
var characterMap = new Dictionary<char, int>();
string regex = "^";
int nextBackreference = 1;
for(int i = 0; i < input.Length; i++)
{
char character = input[i];
if(!characterMap.ContainsKey(character))
{
regex += "(.)";
characterMap[character] = nextBackreference;
nextBackreference++;
}
else
{
regex += (@"\" + characterMap[character]);
}
}
regex += "$";
はmatter
にとっては、この正規表現を生成します:^(.)(.)(.)\3(.)(.)$
。 acquaintance
の場合は、^(.)(.)(.)(.)\1(.)(.)(.)\1\6\2(.)$
です。もちろん、この正規表現を少し後で最適化することができます(例えば2番目の場合は^(.)(.)..\1.(.).\1\3\2$
)。いずれの場合でも、この1つの特定の繰り返しパターンをチェックする再利用可能な正規表現が得られます。
EDIT:与えられた正規表現ソリューションには警告があります。入力文字列の複数の文字をテスト文字列の1文字にマッピングすることができます(最後の例と矛盾します)。正しい正規表現の解決策を得るには、既に一致した文字を禁止するためにさらに進んでいく必要があります。だから、acquaintance
はこのひどい正規表現を生成する必要があります:
^(.)(?!\1)(.)(?!\1|\2)(.)(?!\1|\2|\3)(.)\1(?!\1|\2|\3|\4)(.)(?!\1|\2|\3|\4|\5)(.)(?!\1|\2|\3|\4|\5|\6)(.)\1\6\2(?!\1|\2|\3|\4|\5|\6|\7)(.)$
をそして、あなたは(否定)文字クラスで後方参照を使用することはできませんので、私は、もっと簡単な方法を考えることはできません。だから、の場合もこれを主張したい場合は、正規表現は最善の選択肢ではありません。
免責事項:私は.NETの教祖ではないので、辞書や文字列を構築する際の配列を歩くのにはベストプラクティスではないかもしれません。しかし、私はあなたが出発点としてそれを使用できることを願っています。
これは有効なパターンですか? – lstern
regexがこの種のパターンマッチングに適したツールであるかどうかは不明です。遭遇した文字を別の文字に変換して、それを第2の文字列で変換して比較してみましょう。したがって、最初に見つかった文字は常にa、2番目は常にbなどです。効率的ではありません。しかし。 –
「同じパターン」では、「同じ繰り返し文字」を意味するのではなく、文字列に同じ文字位置/エントロピーが含まれていますか?だから、 'abc' = 'def'、 'aab' = 'ccd'、 'fggh'!= 'abcd'? – newfurniturey