2

我试图从数字数组中生成所有有效的数字组合。假设我们有以下内容:

设arr=[1,2,9,4,7];

我们需要输出如下内容:

1 2 9 4 71 2 9 471 2 94 71 2 9471 29 4 71 29 471 294 71 294712 9 4 712 9 4712 94 712 947129 4 7129 471294 712947

无效的数字是91、497、72等等。

我试过了,但对结果不满意:

常数组合=(arr)=>{设i,j,temp;让结果=[];设arrLen=arr.length;let power=数学pow;让组合=幂(2,arrLen);对于(i=0;i<组合;i+=1){温度=“”;对于(j=0;j<arrLen;j++){if((i&功率(2,j)){温度+=arr[j];}}结果推送(temp);}返回结果;}const结果=组合([1,2,9,4,7]);console.log(结果);
.as-console-wrapper{最大高度:100%!重要;顶部:0;}

有什么想法吗?

5
  • 2
    不满意?您需要指定您遇到的问题或错误。 评论 2017年12月26日11:19
  • 你想用这个问题解决什么问题? 评论 2017年12月26日11:20
  • 校验github.com/dankogai/js-组合-你可能会找到适合排列的方法 评论 2017年12月26日11:21
  • @Xufox你的代码完全符合我的要求。谢谢。但很难理解它是如何工作的。 评论 2017年12月26日11:37
  • @亚历山大·塔尔戈夫我已经在回答中解释过了。 评论 2017年12月26日12:23

4个答案4

重置为默认值
4

此代码执行您想要的操作:

常量arr=[1,2,9,4,7],结果=数组.from({length:2**(arr.length-1)},(_,index)=>index.toString(2).padStart(arr.longth-1,“0”).map((binary)=>JSON.parse(“[”+arr.map((num,position)=>num+(Number(binary[position]))?“,”:“”).加入(“”)+“]”);console.log(结果);
.as-console-wrapper{最大高度:100%!重要;顶部:0;}

其结果是:

[[12947],[1294, 7],[129, 47],[129, 4, 7],[12, 947],[12, 94, 7],[12, 9, 47],[12, 9, 4, 7],[1, 2947],[1, 294, 7],[1, 29, 47],[1, 29, 4, 7],[1, 2, 947],[1, 2, 94, 7],[1, 2, 9, 47],[1, 2, 9, 4, 7]]

假设预期结果不依赖于顺序,空格表示二进制模式:

12947     => 00001294 7    => 0001129 47    => 00101 29 47   => 10101 2 9 4 7 => 1111

我们可以利用这个模式将计数器转换为二进制字符串0因此它始终保持4位数长:

index.toString(2).padStart(arr.length-1,“0”)

对于n个中的数字阿珥,正好有2个n个- 1组合,所以我们使用:

{长度:2**(arr.length-1)}

这是一个具有长度属性2arr.长度- 1.

我们将这两件事结合在一起阵列起始位置接受两个参数的调用:

  • 要转换为数组的对象
  • 映射每个插槽的函数

使用长度属性转换为数组意味着我们使用长度许多插槽。

映射函数接受槽的索引作为第二个参数。我们只使用索引作为二进制数的计数器。

最后,整个表达式:

数组.from({length:2**(arr.length-1)},(_,index)=>index.toString(2).padStart(arr.longth-1,“0”)

计算为以下数组:

["0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"]

我们需要进一步将此映射到最终结果:

.map((二进制)=>…)

对于每个数组元素,二元的是上面数组中的二进制字符串之一。

为了转弯,例如。"0110"变成类似这样的东西"12,9,47",我们需要地图结束阿珥也。每个数字号码阿珥后面应该跟,位置,如果二元的1位置:

arr.map((num,position)=>num+(数字(二进制[位置])?“,”:“)。联接(”“)

表达式(数字(二进制[位置])?"," : "")评估二元的以数字的形式在指定位置。如果是的话真实的,即除0,其计算结果为",",如果是虚伪的,即。0,其计算结果为"".

所以中间数组看起来像["1", "2,", "9,", "4", "7"]。所有这些都结合在一起"12,9,47".

然后,使用JSON.parse(“[”++ "]")它被作为数组处理和解析,因此它变成[12, 9, 47]。由于这些步骤适用于每个二进制字符串,因此最终会得到最终结果。


  • 2**(棱长-1)可以替换为数学.pow(2,arr.length-1)如果不支持ECMAScript 7。
  • {长度:2**(arr.length-1)}可以替换为新数组(2**(arr.length-1)).
  • (数字(二进制[位置])?"," : "")可以替换为[“,”,“][数字(二进制[位置])]。在这种情况下,计算的数字将用作临时数组的索引。
2
  • 神奇的兄弟,我很高兴看到这个答案:)二进制模式位置的描述 评论 2017年12月26日12:24
  • 一直以来,指数运算都是错误的……现在解决了……我希望如此。 评论 2018年6月30日2:28

因此,您需要迭代所有数字之间的“空格”和“非空格”的所有组合。使用n个项目,将有n-1个空间,和2**(n-1)不同的列表。

所以你可以这样做来获得所有可能的列表:

常量组合=arr=>{常量长度=arr.length;const n=数学pow(2,len-1);常量组合=[];for(设i=0;i<n;i++){设this_combination=[arr[0]];for(设j=1;j<len;j++){if(i&Math.pow(2,j-1)){//如果第j位打开,则没有空格。附加到最后一个元素。const last_index=this_combination.length-1;this_combination[last_index]=+(this_conbination[拉斯t_index]+''+arr[j]);}其他{//否则,创建一个新的列表项。this_combination.push(arr[j]);}}//考虑将此函数设为生成器,并将其设为yield。组合.push(this_combination);}收益组合;}const结果=组合([1,2,9,4,7]);console.log(result.map(line=>line.join('')).jjoin('\n'));
.as-console-wrapper{最大高度:100%!重要;顶部:0;}

如果您想单独使用每个项目,对于数组中的每个项目,请将其与其他项目组合,然后只使用下一个项目,然后再使用下两个项目,以此类推,直到结束:

常量组合=arr=>{常量长度=arr.length;常量组合=[];for(设i=0;i<len;i++){设项目=arr[i];组合。推送(项);for(设j=i+1;j<len;j++){项目=+(项目+''+arr[j]);组合。推送(项);}}收益组合;}const结果=组合([1,2,9,4,7]);console.log(result.join('\n'));
.as-console-wrapper{最大高度:100%!重要;顶部:0;}

1

您可以采用递归方法,迭代数组并插入空格或不插入空格,然后使用增量索引派生对同一函数的调用。

函数组合(数组){函数叉(i,p){如果(i===数组长度){result.push(p);回报;}fork(i+1,p+''+数组[i]);fork(i+1,p+数组[i]);}var结果=[];fork(1,数组[0].toString());返回结果;}控制台.log(组合([1,2,9,4,7]);
.as-console-wrapper{最大高度:100%!重要;顶部:0;}

0

您可以通过使用下面的代码来实现这一点,其中使用了3个指针,

  1. 第一个指针将第0个位置打印到光标位置。
  2. 第二个指针在每次迭代中将光标打印到不同的位置。
  3. 第三个指针将光标位置打印到最后一个位置。

设arr=[1,2,9,4,7];console.log(arr.join(','));for(设diff=2;diff<=arr.length;diff++){对于(i=0,j=diff;arr.length>=i+diff;j++,i++){var温度=[];如果(i>0)临时推送(arr.slice(0,i).join(','));临时推送(arr.slice(i,j).join(''));如果(j<arr.长度)临时推送(arr.slice(j,arr.length).join(','));console.log(临时联接(','));}}

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.