最も簡単な方法は、おそらく両方の文字列を同時に手動で調べて、実行中に辞書(対応する文字を一致させる)を作成することです。
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つの繰り返しパターンを複数の文字列に対してチェックする場合に役立つ可能性があります。今回は、キャラクターをそれらの後方参照に関連付けます。
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つの特定の繰り返しパターンをチェックする再利用可能な正規表現が得られます。
編集:指定された正規表現ソリューションには注意が必要です。これにより、入力文字列の複数の文字をテスト文字列の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の第一人者ではないため、辞書や文字列を作成する際に配列をウォークスルーする際のベストプラクティスではない可能性があります。しかし、それを出発点として使用できることを願っています。