我将输入作为int并根据该输入我想要两个字符的组合, 例如 我输入为2,我有两个字符x和y所以我想要像
这样的组合 xx,yy,xy,yx
如果输入为3,我想要
xxx,xyy,xxy,xyx,yxx,yyy,yxy.yyx
等等,我尝试使用以下代码,
int input1 = 4;
Double totalpossibilities = Math.Pow(2, input1);
string[] PArray = new string[Convert.ToInt16(totalpossibilities)];
char[] chars = new char[] { 'x', 'y'};
for (int i = 0; i < totalpossibilities; i++)
{
string possibility = "" ;
for (int j = 0; j < input1; j++)
{
Random random = new Random();
int r = random.Next(chars.Length);
char randomChar = chars[r];
possibility = possibility + randomChar;
}
if (PArray.Contains(possibility))
{
i--;
}
else
PArray[i] = possibility;
}
但是你可以看到我正在使用随机函数所以我需要很长时间才能完成,是否有任何不同的逻辑?
答案 0 :(得分:4)
使用从here逐字复制的笛卡尔积扩展方法的副本:
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] {item}));
}
然后在您的代码中,您可以:
IEnumerable<char> possibleCharacters = "xy";//change to whatever
int numberOfDigits = 3;
var result = Enumerable.Repeat(possibleCharacters, numberOfDigits)
.CartesianProduct()
.Select(chars => new string(chars.ToArray()));
//display (or do whatever with) the results
foreach (var item in result)
{
Console.WriteLine(item);
}
答案 1 :(得分:3)
你可以运行一个从0到totalpossibilities的for循环。 例如,在迭代20将i转换为二进制,这将导致“10100”。 将结果填充到input1个字符,例如(对于8个位置):00010100 然后转换为字符串并用“x”替换所有的零,所有的都用“y”替换。
int places = 4;
Double totalpossibilities = Math.Pow(2, places);
for (int i = 0; i < totalpossibilities; i++)
{
string CurrentNumberBinary = Convert.ToString(i, 2).PadLeft(places, '0');
CurrentNumberBinary = CurrentNumberBinary.Replace('0', 'x');
CurrentNumberBinary = CurrentNumberBinary.Replace('1', 'y');
Debug.WriteLine(CurrentNumberBinary);
}
答案 2 :(得分:0)
如果你总是有2个字符,那么最简单的方法是使用整数组合性质。如果你采用从2 ^ n到2 ^(n + 1) - 1的所有数字的二进制形式,你会注意到它代表长度为n的所有可能的'0'和'1'的组合。)。
对于超过2个字符,我会使用类似的方法,但使用不同的基础。
答案 3 :(得分:0)
以下是List<>
的解决方案。推广到任意数量的字母。
static List<string> letters = new List<string> { "x", "y", };
static List<string> MakeList(int input)
{
if (input < 0)
throw new ArgumentOutOfRangeException();
var li = new List<string> { "", };
for (int i = 0; i < input; ++i)
li = Multiply(li);
return li;
}
static List<string> Multiply(List<string> origList)
{
var resultList = new List<string>(origList.Count * letters.Count);
foreach (var letter in letters)
resultList.AddRange(origList.Select(s => letter + s));
return resultList;
}
答案 4 :(得分:0)
svenv回答是对这个问题的正确(而且非常聪明)的答案,但我想我会提供一个通用的解决方案来生成令牌集的所有排列,这可能对其他可能有类似问题的人有用。< / p>
public class Permutations
{
public static string[][] GenerateAllPermutations(string[] tokens, int depth)
{
string[][] permutations = new string[depth][];
permutations[0] = tokens;
for (int i = 1; i < depth; i++)
{
string[] parent = permutations[i - 1];
string[] current = new string[parent.Length * tokens.Length];
for (int parentNdx = 0; parentNdx < parent.Length; parentNdx++)
for (int tokenNdx = 0; tokenNdx < tokens.Length; tokenNdx++)
current[parentNdx * tokens.Length + tokenNdx] = parent[parentNdx] + tokens[tokenNdx];
permutations[i] = current;
}
return permutations;
}
public static void Test()
{
string[] tokens = new string[] { "x", "y", "z" };
int depth = 4;
string[][] permutations = GenerateAllPermutations(tokens, depth);
for (int i = 0; i < depth; i++)
{
foreach (string s in permutations[i])
Console.WriteLine(s);
Console.WriteLine(string.Format("Total permutations: {0}", permutations[i].Length));
Console.ReadKey();
}
}
}
干杯,