Создайте все перестановки строки постепенно c # - PullRequest
2 голосов
/ 02 февраля 2011

Я пытаюсь создать функцию, которая будет создавать все перестановки строки в пошаговом режиме. Я хотел бы начать с:

AAAAA
...
AAAAB
...
ACCCC
...
...
ZZZZZ

Я оглянулся и не могу найти ничего подобного. Я пытался создать его, но он не был постепенно.

Есть предложения?

Ответы [ 5 ]

4 голосов
/ 03 февраля 2011

«Перестановка», которую вы описываете, более известна как декартово произведение.Если у вас есть произвольное число последовательностей, из которых вам нужно сформировать декартово произведение, см. Мой ответ на этот вопрос по теме:

Генерация всех возможных комбинаций

2 голосов
/ 02 февраля 2011

Обычно я не помог бы этим результатам типа грубой силы ... но видя, сколько бесполезных результатов вы получите из набора, я полагал, что я просто добавлю это.... если вам просто нужно следующее значение, вы можете сделать что-то вроде этого ...

public static string Increment(string input)
{
    var array = input.ToCharArray();
    if (array.Any(c => c < 'A' || c > 'Z'))
        throw new InvalidOperationException();

    for (var i = array.Length-1; i >= 0; i--)
    {
        array[i] = (char)(array[i] + 1);
        if (array[i] > 'Z')
        {
            array[i] = 'A';
            if (i == 0)
                return 'A' + new string(array);
        }
        else
            break;
    }
    return new string(array);
}
1 голос
/ 02 февраля 2011

Другой вариант, где у меня была идея использовать арифметику по модулю. Обратите внимание, что я опустил символ до {A, B, C}, чтобы проверить его, так как переход к Z для 5 букв - это много строк.

public IEnumerable<char[]> AlphaCombinations(int length = 5, char startChar = 'A', char endChar = 'C')
{
    int numChars = endChar - startChar + 1;
    var s = new String(startChar, length).ToCharArray();    
    for (int it = 1; it <= Math.Pow(numChars, length); ++it) 
    {        
        yield return s;

        for (int ix = 0; ix < s.Length; ++ix) 
            if (ix == 0 || it % Math.Pow(numChars, ix) == 0) 
                s[s.Length - 1 - ix] = (char)(startChar + (s[s.Length - 1 - ix] - startChar + 1) % numChars);
    }
}

...

foreach (var s in AlphaCombinations(5))
{
    Console.WriteLine(s);
}
0 голосов
/ 02 февраля 2011

Вот дружественный код LINQPad, в котором используется лямбда-выражение.

void Main()
{
    var chars = Enumerable.Range(65, 26);

    var strings = chars.SelectMany (a => 
        {
            return chars.SelectMany (b => chars.SelectMany (c => 
                {
                    return chars.SelectMany (d => 
                    {
                        return chars.Select (e => {return new string(new char[] {(char)a, (char)b, (char)c, (char)d, (char)e});});
                    });
                }));
        });

    strings.Dump();
}
0 голосов
/ 02 февраля 2011

быстро разбились - я ожидаю, что это можно сделать лучше:

public static IEnumerable<string> GenerateStrings(int length = 5)
{
  var buffer = new char[length];
  for (int i = 0; i < length; ++i)
  {
    buffer[i] = 'A';
  }
  for(;;)
  {
    yield return new string(buffer);

    int cursor = length;
    for(;;)
    {
      --cursor;
      if (cursor < 0)
      {
        yield break;
      }

      char c = buffer[cursor];
      ++c;
      if (c <= 'Z')
      {
        buffer[cursor] = c;
        break;
      }
      else
      {
        buffer[cursor] = 'A';
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...