1

私はintとして入力を与えており、その入力に従って2つの文字の組み合わせが必要です。たとえば、2 として 入力を与えており、xとyの2つの文字があるので、次のような組み合わせが必要です。

    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;
        }

しかし、ご覧のとおり、ランダム関数を使用しているので、完了するのに時間がかかりすぎます。別のロジックはありますか?

4

5 に答える 5

4

ここから逐語的にコピーされたデカルト積拡張メソッドのコピーを使用します。

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);
}
于 2012-05-15T18:05:31.417 に答える
3

0からtotalpossibilitiesまでforループを実行できます。iをバイナリに変換します。たとえば、反復20で、これは「10100」になります。結果をinput1文字にパディングします。たとえば(8桁の場合):000010100次に、文字列に変換し、すべてのゼロを「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);
        }
于 2012-05-15T18:04:03.100 に答える
0

常に2文字の場合、最も簡単な方法は整数の組み合わせの性質を使用することです。2 ^nから2^(n + 1)-1までのすべての数値のバイナリ形式をとると、長さnの「0」と「1」のすべての可能な組み合わせを表すことに気付くでしょう:)。

2文字を超える場合は、同様のアプローチを使用しますが、ベースが異なります。

于 2012-05-15T18:13:35.577 に答える
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;
}
于 2012-05-15T19:26:23.287 に答える
0

svenvの答えは、質問に対する正しい(そして非常に賢い)答えですが、同様の問題を抱えている可能性のある他の人に役立つ可能性のあるトークンのセットのすべての順列を生成するための一般的なソリューションを提供すると思いました。

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();
        }
    }
}

乾杯、

于 2012-05-15T19:26:58.327 に答える