有効な文字のセットから文字のすべての組み合わせを生成する必要があります; このセットを呼びましょうvalidChars
。基本的に、長さNの組み合わせの各セットは、validChars
それ自体とのデカルト積であり、N回です。これは、Linqを使用して行うのは非常に簡単です。
char[] validChars = ...;
var combinationsOfLength1 =
from c1 in validChars
select new[] { c1 };
var combinationsOfLength2 =
from c1 in validChars
from c2 in validChars
select new[] { c1, c2 };
...
var combinationsOfLength12 =
from c1 in validChars
from c2 in validChars
...
from c12 in validChars
select new[] { c1, c2 ... c12 };
var allCombinations =
combinationsOfLength1
.Concat(combinationsOfLength2)
...
.Concat(combinationsOfLength12);
明らかに、特に最大長が事前にわからない場合は、各長さのコードを手動で記述したくありません...
Eric Lippertは、任意の数のシーケンスのデカルト積を生成することについての記事を持っています。この記事で提供されている拡張方法を使用するCartesianProduct
と、次のように長さNのすべての組み合わせを生成できます。
var combinationsOfLengthN = Enumerable.Repeat(validChars, N).CartesianProduct();
長さ1からMAXまでのすべての組み合わせが必要なので、次のようなことができます。
var allCombinations =
Enumerable
.Range(1, MAX)
.SelectMany(N => Enumerable.Repeat(validChars, N).CartesianProduct());
allCombinations
は、IEnumerable<IEnumerable<char>>
文字列のシーケンスとして結果を取得する場合は、射影を追加するだけです。
var allCombinations =
Enumerable
.Range(1, MAX)
.SelectMany(N => Enumerable.Repeat(validChars, N).CartesianProduct())
.Select(combination => new string(combination.ToArray()));
それは確かに最も効率的な解決策ではないことに注意してください、しかし少なくともそれは短くて読みやすいです...