增量创建字符串的所有排列 C#

发布于 2024-10-15 09:07:21 字数 169 浏览 8 评论 0原文

我正在尝试创建一个函数,该函数将以增量方式创建字符串的所有排列。我想首先:

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

我环顾四周,似乎找不到任何类似的东西。我尝试创建它,但它不是增量的。

有什么建议吗?

I am trying to create a function that will create all permutations of a string in an incremental fashion. I would like to start at:

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

I have looked around, and can't seem to find anything of that sort. I tried to create it, but it wasn't incrementally.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅沫记忆 2024-10-22 09:07:21

您所描述的“排列”更广为人知的是笛卡尔积。如果您需要形成笛卡尔积的任意数量的序列,请参阅我对此主题的回答:

生成所有可能的组合

The "permutation" you are describing is better known as the Cartesian product. If you have an arbitrary number of sequences that you need to form the Cartesian product of, see my answer to this question on the subject:

Generating all Possible Combinations

羁客 2024-10-22 09:07:21

通常我不会帮助这些蛮力类型的结果......但是看到你会从集合中得到多少无用的结果,我想我只是把它扔进去。

var query = from c0 in Enumerable.Range(0, 26)
            from c1 in Enumerable.Range(0, 26)
            from c2 in Enumerable.Range(0, 26)
            from c3 in Enumerable.Range(0, 26)
            from c4 in Enumerable.Range(0, 26)
            select new string(
                new [] {
                    (char)('A' + c0),
                    (char)('A' + c1),
                    (char)('A' + c2),
                    (char)('A' + c3),
                    (char)('A' + c4),
                }
                );

顺便说一句......如果你只想要下一个值,你可以做这样的事情...

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

Normally I wouldn't help these brute force type results... but seeing how many useless result you will get out of the set I figured I'd just toss this in.

var query = from c0 in Enumerable.Range(0, 26)
            from c1 in Enumerable.Range(0, 26)
            from c2 in Enumerable.Range(0, 26)
            from c3 in Enumerable.Range(0, 26)
            from c4 in Enumerable.Range(0, 26)
            select new string(
                new [] {
                    (char)('A' + c0),
                    (char)('A' + c1),
                    (char)('A' + c2),
                    (char)('A' + c3),
                    (char)('A' + c4),
                }
                );

BTW... if you just want the next value you can do something like this...

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);
}
小嗲 2024-10-22 09:07:21

一个不同的变体,我想到了使用模运算。请注意,我将字符降低到 {A,B,C} 来测试它,因为将 5 个字母提高到 Z 会产生很多字符串。

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

A different variant where I had the idea of using modulo arithmetic. Note that I lowered the character to {A,B,C} to test it, since going up to Z for 5 letters is a lot of strings.

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);
}
小巷里的女流氓 2024-10-22 09:07:21

很快就被打败了——我希望这可以做得更好:

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

Bashed out quickly - I expect this could be done better:

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';
      }
    }
  }
}
咆哮 2024-10-22 09:07:21

这是 LINQPad 友好的代码,它使用 lambda 表达式。

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

Here is the LINQPad friendly code and it uses lambda expression.

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文