在C#中生成一组字符的所有组合和排列,到指定的长度。

huangapple go评论109阅读模式
英文:

All combinations and permutations of a set of characters to a given length in c#

问题

我有一组字符:“ab”,我需要每个给定长度的组合和排列。

如果我给定长度为3,我需要像这样的集合:
a,
b,
aa,
ab,
ba,
bb,
aaa,
aab,
aba,
abb,
baa,
bab,
bba,
bbb

以此类推。

我找到了一个相对不错的解决方案(https://stackoverflow.com/a/3640224/18535919),但我认为它有点复杂。过去我找到过一个好的解决方案,但现在找不到了。

static int maxlength = 3;
static string ValidChars = "abc";
static void Dive(string prefix, int level)
{
       level += 1;
       foreach (char c in ValidChars)
       {
            Console.WriteLine(prefix + c);
            if (level < maxlength)
            {
                Dive(prefix + c, level);
            }
      }
}
英文:

I have a set of characters: "ab", I need every combinations and permutations of it to given length.
What I need sets like these if I give the length of 3:
a,
b,
aa,
ab,
ba,
bb,
aaa,
aab,
aba,
abb,
baa,
bab,
bba,
bbb

and so on.

I found a sort of good solution (https://stackoverflow.com/a/3640224/18535919), but I think it is a bit complicated. I have found a good solution in the past but I can not find it again.

static int maxlength = 3;
static string ValidChars = &quot;abc&quot;;
static void Dive(string prefix, int level)
{
       level += 1;
       foreach (char c in ValidChars)
       {
            Console.WriteLine(prefix + c);
            if (level &lt; maxlength)
            {
                Dive(prefix + c, level);
            }
      }
}

答案1

得分: 1

以下是翻译好的部分:

你当前的代码看起来足够简单,但如果你正在寻找一个不使用递归的通用方法,你可以尝试像这样的东西(坦白地说,这更加复杂,但可以在一般情况下使用):

示例

using System.Linq;

...

private static IEnumerable<T[]> SolveMe<T>(int maxLength, IEnumerable<T> chars) {
  if (maxLength < 0)
    throw new ArgumentOutOfRangeException(nameof(maxLength));

  if (chars is null)
    throw new ArgumentNullException(nameof(chars));

  var letters = chars.Distinct().ToArray();

  if (letters.Length == 0)
     yield break;

  for (var agenda = new Queue<T[]>(new[] { Array.Empty<T>() }); 
           agenda.Peek().Length < maxLength;) {
    var current = agenda.Dequeue();

    foreach (var letter in letters) {
      var next = current.Append(letter).ToArray();

      agenda.Enqueue(next);

      yield return next;
    }
  }
}

演示:

// 所有解决方案作为列表
List<char[]> result = SolveMe(3, "ab").ToList();

var report = string.Join(", ", result.Select(item => string.Concat(item)));

Console.Write(report);

输出:

a, b, aa, ab, ba, bb, aaa, aab, aba, abb, baa, bab, bba, bbb
英文:

Your current code looks simple enough, however if you are looking for generalized approach which doesn't use recursion you can try something like this (frankly speaking it's more complicated, but can be used in general case):

Fiddle

using System.Linq;

...

private static IEnumerable&lt;T[]&gt; SolveMe&lt;T&gt;(int maxLength, IEnumerable&lt;T&gt; chars) {
  if (maxLength &lt; 0)
    throw new ArgumentOutOfRangeException(nameof(maxLength));

  if (chars is null)
    throw new ArgumentNullException(nameof(chars));

  var letters = chars.Distinct().ToArray();

  if (letters.Length == 0)
     yield break;

  for (var agenda = new Queue&lt;T[]&gt;(new[] { Array.Empty&lt;T&gt;() }); 
           agenda.Peek().Length &lt; maxLength;) {
    var current = agenda.Dequeue();

    foreach (var letter in letters) {
      var next = current.Append(letter).ToArray();

      agenda.Enqueue(next);

      yield return next;
    }
  }
}

Demo:

// All solutions as a list
List&lt;char[]&gt; result = SolveMe(3, &quot;ab&quot;).ToList();

var report = string.Join(&quot;, &quot;, result.Select(item =&gt; string.Concat(item)));

Console.Write(report);

Output:

a, b, aa, ab, ba, bb, aaa, aab, aba, abb, baa, bab, bba, bbb

答案2

得分: 1

你可以使用递归技巧来生成给定字符的所有组合和排列。请查看下面的代码:

class Program
{
    static void Main(string[] args)
    {
        string characters = "ab";
        int maxLength = 3;
        var output = GenerateCombinations(characters, maxLength, "");
        Console.WriteLine(string.Join(", ", output.Select(item => string.Concat(item))));
    }

    static IEnumerable<string> GenerateCombinations(string characters, int maxLength, string current)
    {
        if (current.Length > 0)
        {
            yield return current;
        }

        if (current.Length < maxLength)
        {
            foreach (char c in characters)
            {
                foreach (string result in GenerateCombinations(characters, maxLength, current + c))
                {
                    yield return result;
                }
            }
        }
    }
}

输出结果: a, aa, aaa, aab, ab, aba, abb, b, ba, baa, bab, bb, bba, bbb

英文:

You can achieve this using recursive techniques to generate all the combinations and permutations of the given characters. Check the below code:

class Program
{
    static void Main(string[] args)
    {
        string characters = &quot;ab&quot;;
        int maxLength = 3;
        var output = GenerateCombinations(characters, maxLength, &quot;&quot;);
        Console.WriteLine(string.Join(&quot;, &quot;, output.Select(item =&gt; string.Concat(item))));
    }

    static IEnumerable&lt;string&gt; GenerateCombinations(string characters, int maxLength, string current)
    {
        if (current.Length &gt; 0)
        {
            yield return current;
        }

        if (current.Length &lt; maxLength)
        {
            foreach (char c in characters)
            {
                foreach (string result in GenerateCombinations(characters, maxLength, current + c))
                {
                    yield return result;
                }
            }
        }
    }
}

Output: a, aa, aaa, aab, ab, aba, abb, b, ba, baa, bab, bb, bba, bbb

huangapple
  • 本文由 发表于 2023年8月10日 17:19:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76874321.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定