【问题标题】:How to generate every possible combination of elements in array between range如何在范围之间生成数组中所有可能的元素组合
【发布时间】:2018-12-14 23:37:49
【问题描述】:

我目前正在使用 Javascript,但对任何东西都开放。我想生成大小为 X 的数组的每个可能的元素组合,其中每个元素只能是 N 个不同的值

例如我的数组大小为 X = 3,不同的值 N = 2

001 011 111 100 110 000 010 101

我认为这就是所有的组合。我觉得这应该是一个常见的编程问题和一个简单的任务,但无法找到任何反映我需要的东西,大多数情况下没有考虑到相同数字多次出现的可能性(例如 111 )

【问题讨论】:

  • 那只是返回一个计数,除非我遗漏了一些明显的东西。我想要所有的组合。
  • 我相信我正在寻找的(经过一些研究)是所有可能的重复排列,尽管我似乎找不到一个好的 javascript sn-p。

标签: javascript algorithm


【解决方案1】:

这可能是你需要的:

function combinations(size, values) {
    var result = [];
    for (let k = 0; k < Math.pow(values, size); k++) {
        result.push(k.toString(values));
    }
    return result
}

它的作用是从 0 计数到 (values^size)-1,同时以 values 为基数表示所有数字。

不填充以一个或多个 0s 开头的组合。如果您想获得 0011、0101 等,请填写它们。

例子:

对于 3 和 2 个不同的值,您将获得:

["0", "1", "10", "11", "100", "101", "110", "111"]

对于 4 号和 3 号不同的值:

["0", "1", "2", "10", "11", "12", "20", "21", … ,"2202", "2210", "2211", "2212", "2220", "2221", "2222"]

【讨论】:

    【解决方案2】:

    您应该将其视为一个递归问题:如何为字母表[0, 1] 生成长度为 3 的组合?好吧,您生成长度为 2 的所有组合,并且对于每个字符串(称为 s),生成两个新结果:0s1s。同样用于生成长度为 2 的组合。

    对于基本情况,长度为 1,我们可以只返回字母表本身。

    这是一些 JavaScript 代码:

    function combine(alphabet, length) {
      if (length === 1) return alphabet;
      let combinations = [];
      for (s of combine(alphabet, length - 1))
        for (c of alphabet)
          combinations.push(c + s);
      return combinations;
    }
    

    或者,如果您想支持获取长度为 0 的组合,您的基本情况可能会返回一个仅包含空字符串的列表:

    function combine(alphabet, length) {
      if (length === 0) return [""];
      let combinations = [];
      for (s of combine(alphabet, length - 1))
        for (c of alphabet)
          combinations.push(c + s);
      return combinations;
    }
    

    【讨论】:

      【解决方案3】:

      这里有一段 c 代码可以帮助你:

      // counter
      #include <iostream>
      using namespace std;
      int main()
      {
          int n,b,k;
          cin>>n>>b;
          int A[n+1];
          for(int i=0;i<=n;i++)
          {
              A[i]=0;    
          }
          while(A[n]!=1)
          {
              for(int i=(n-1);i>=0;i--)
              {
                  cout<<A[i]<<"  ";
              }
              cout<<"\n";
              A[0]++;
              k=0;
      
          while(A[k]==b)
          {
              A[k]=0;
              A[k+1]++;
              k++;
          }
          }
          return 0;
      }
      

      应该很容易弄明白,改成java作为练习吧。

      【讨论】:

        【解决方案4】:

        处理这个问题的一种方便方法是在递归函数的参数中传递状态。然后你可以简化回溯并使用一些很好的 ES6 便利来使代码简短易读:

        function makeCombo(vals, n, current = [], res = []) {
          if (current.length == n) return res.push(current)           // stop if the current call is the target length
          vals.forEach(v => makeCombo(vals, n, [...current, v], res)) // other wise loop over values and recurse   
          return res
        }
        
        
        // binary counting:
        console.log(makeCombo([0, 1], 3).map(a => a.join(',')))
        
        // more values:
        console.log(makeCombo(['a', 'b', 'c'], 3).map(a => a.join(',')))

        【讨论】:

          猜你喜欢
          • 2019-08-06
          • 1970-01-01
          • 2013-01-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-10
          • 2022-01-18
          相关资源
          最近更新 更多