【问题标题】:Getting all the combinations in an array获取数组中的所有组合
【发布时间】:2021-09-10 07:03:01
【问题描述】:

假设我有以下数组:

var arr = new[] { "A", "B", "C" };

如何生成仅包含两个字符且没有两个相同字符的所有可能组合(例如,ABBA 相同)。例如,使用上面的数组会产生:

AB
AC
BC

请注意,此示例已被简化。所需的数组和字符串的长度会更大。

如果有人能提供帮助,我将不胜感激。

【问题讨论】:

  • 你需要 AB、AC、BC 和 ABC 吗?

标签: c#


【解决方案1】:

让我们扩展它,也许我们可以看到模式:

string[] arr = new string[] { "A", "B", "C", "D", "E" };

//arr[0] + arr[1] = AB
//arr[0] + arr[2] = AC
//arr[0] + arr[3] = AD
//arr[0] + arr[4] = AE

//arr[1] + arr[2] = BC
//arr[1] + arr[3] = BD
//arr[1] + arr[4] = BE

//arr[2] + arr[3] = CD
//arr[2] + arr[4] = CE

//arr[3] + arr[4] = DE

我在这里看到两个循环。

  • 第一个(外部)循环从 0 变为 4 (arr.Length - 1)
  • 第二个(内部)循环从外部循环计数器 + 1 到 4 (arr.Length)

现在应该很容易将其转换为代码!

【讨论】:

    【解决方案2】:
    【解决方案3】:

    这段代码

    var strs = new[] {"A", "B", "C", "D"};
    var combinations = CreateCombinations(0, "", strs);
    var text = string.Join(", ", combinations);
    
    private List<string> CreateCombinations(int startIndex, string pair, string[] initialArray)
        {
            var combinations = new List<string>();
            for (int i = startIndex; i < initialArray.Length; i++)
            {
                var value = $"{pair}{initialArray[i]}";
                combinations.Add(value);
                combinations.AddRange(CreateCombinations(i + 1, value, initialArray));
            }
    
            return combinations;
        }
    

    文本变量将包含

    A, AB, ABC, ABCD, ABD, AC, ACD, AD, B, BC, BCD, BD, C, CD, D
    

    【讨论】:

      【解决方案4】:

      您要求的是组合,而不是排列(后一个术语意味着顺序很重要)。无论如何,它是递归的经典用途。在伪代码中:

      def combs(thearray, arraylen, currentindex, comblen):
        # none if there aren't at least comblen items left,
        # or comblen has gone <= 0
        if comblen > arraylen - currentindex or comblen <= 0:
          return
        # just 1 if there exactly comblen items left
        if comblen == arraylen - currentindex:
          yield thearray[currentindex:]
          return
        # else, all combs with the current item...:
        for acomb in combs(thearray, arraylen, currentindex+1, comblen-1):
          yield thearray[currentindex] + acomb
        # ...plus all combs without it:
        for acomb in combs(thearray, arraylen, currentindex+1, comblen):
          yield acomb
      

      【讨论】:

        【解决方案5】:

        由于排序无关紧要,这些实际上是组合而不是排列。无论如何,有一些示例代码here(你想要标题为“组合(即,没有重复)”的部分。

        【讨论】:

          【解决方案6】:
          public string[] Permute(char[] characters)
          {
              List<string> strings = new List<string>();
              for (int i = 0; i < characters.Length; i++)
              {
                  for (int j = i + 1; j < characters.Length; j++)
                  {
                      strings.Add(new String(new char[] { characters[i], characters[j] }));
                  }
              }
          
              return strings.ToArray();
          }
          

          【讨论】:

            【解决方案7】:

            它是 1 到 n-1 或 n(n-1) / 2 的总和。

            int num = n * ( n - 1 ) / 2;
            

            显然,您可以使用一对阶乘来概括 n * ( n - 1 ),无论您尝试做什么(字符串大小)。

            【讨论】:

              【解决方案8】:

              没有测试也不是最快的,但是:

              IEnumerable<String> Combine(String text, IEnumerable<String> strings)
              {
                  return strings.Select(s => text + s).Concat(Combine(strins.Take(1).First(), strings.Skip(1))
              }
              

              呼叫:

              foreach (var s in Combine("" , arrayOfStrings))
              {
                   // print s
              }
              

              【讨论】:

                【解决方案9】:

                为一个被标记为重复的问题写了一个答案,指向这里。

                var arr = new[] { "A", "B", "C" };
                
                var arr2 = arr1.SelectMany(
                    x => arr1.Select(
                        y => x + y));
                

                在 VS2013 中枚举到控制台时产生了正确的输出。 SelectMany 将扁平化从内部Select 生成的内部IEnumerable

                【讨论】:

                  【解决方案10】:

                  您正在寻找的是沿着以下伪代码行的双循环。

                  for(int i = FirstElement; i<= LastElement; increment i) {
                      for(j = i; j<= lastElement; increment j) {
                          if(i != j) {
                              print (i, j)
                          }
                      }
                  }
                  

                  【讨论】:

                  • 这是对组合学的过度简化。当组合的数量变大时,您的代码将如何工作,例如 26 字母数组中的 10 字母组合(26 选择 10,无重复)?
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-03-20
                  相关资源
                  最近更新 更多