我正在尝试从数组中生成所有有效的数字组合。我们假设我们有以下内容:
let arr = [1, 2, 9, 4, 7];
我们需要输出这样的东西:
1 2 9 4 7
1 2 9 47
1 2 94 7
1 2 947
1 29 4 7
1 29 47
1 294 7
1 2947
12 9 4 7
12 9 47
12 94 7
12 947
129 4 7
129 47
1294 7
12947
无效的数字是91,497,72等等。
我尝试了这个,但我对结果不满意:
const combination = (arr) => {
let i, j, temp;
let result = [];
let arrLen = arr.length;
let power = Math.pow;
let combinations = power(2, arrLen);
for (i = 0; i < combinations; i += 1) {
temp = '';
for (j = 0; j < arrLen; j++) {
if ((i & power(2, j))) {
temp += arr[j];
}
}
result.push(temp);
}
return result;
}
const result = combination([1, 2, 9, 4, 7]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
有什么想法吗?
答案 0 :(得分:3)
所以你需要迭代&#34;空间&#34;的所有组合。和#34;不是空间&#34;在所有数字之间。对于n
项,会有n - 1
个空格和2 ** (n - 1)
个不同的列表。
所以你可以做这样的事情来获得所有可能的列表:
const combination = arr => {
const len = arr.length;
const n = Math.pow(2, len - 1);
const combinations = [];
for (let i = 0; i < n; i++) {
let this_combination = [arr[0]];
for (let j = 1; j < len; j++) {
if (i & Math.pow(2, j - 1)) {
// If the jth bit is on, no space. Append to the last element.
const last_index = this_combination.length - 1;
this_combination[last_index] = +(this_combination[last_index] + '' + arr[j]);
} else {
// Otherwise create a new list item.
this_combination.push(arr[j]);
}
}
// Consider making this function a generator and making this a yield.
combinations.push(this_combination);
}
return combinations;
}
const result = combination([1, 2, 9, 4, 7]);
console.log(result.map(line => line.join(' ')).join('\n'));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
如果你想要每个单独的项目,对于数组中的每个项目,将它与其他项目合并,然后只是下一个项目,然后是接下来的两个项目等,直到结束:
const combination = arr => {
const len = arr.length;
const combinations = [];
for (let i = 0; i < len; i++) {
let item = arr[i];
combinations.push(item);
for (let j = i + 1; j < len; j++) {
item = +(item + '' + arr[j]);
combinations.push(item);
}
}
return combinations;
}
const result = combination([1, 2, 9, 4, 7]);
console.log(result.join('\n'));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 1 :(得分:3)
此代码可以满足您的需求:
const arr = [1, 2, 9, 4, 7],
result = Array.from({length: 2 ** (arr.length - 1)}, (_, index) => index.toString(2).padStart(arr.length - 1, "0"))
.map((binary) => JSON.parse("[" + arr.map((num, position) => num + (Number(binary[position]) ? "," : "")).join("") + "]"));
console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
结果是:
[
[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 => 0000
1294 7 => 0001
129 47 => 0010
…
1 29 47 => 1010
…
1 2 9 4 7 => 1111
我们可以将这个模式与我们转换为二进制字符串的计数器一起使用。我们还用0
填充该字符串,因此它总是保持4位数字:
index.toString(2).padStart(arr.length - 1, "0")
对于arr
中的 n 数字,正好有2个 n - 1 组合,因此我们使用:
{length: 2 ** (arr.length - 1)}
这是一个length
属性为2 arr.length
- 1 的对象。
我们将这些内容组合成Array.from
调用,该调用接受两个参数:
将具有length
属性的对象转换为数组意味着我们创建了一个length
多个插槽的数组。
映射函数接受插槽的索引作为第二个参数。我们只使用索引 - 作为二进制数的计数器。
所以,最后这个表达方式:
Array.from({length: 2 ** (arr.length - 1)}, (_, index) => index.toString(2).padStart(arr.length - 1, "0"))
评估以下数组:
[
"0000",
"0001",
"0010",
"0011",
"0100",
"0101",
"0110",
"0111",
"1000",
"1001",
"1010",
"1011",
"1100",
"1101",
"1110",
"1111"
]
我们需要进一步将其映射到最终结果:
.map((binary) => …)
对于每个数组元素,binary
是上面数组中的二进制字符串之一。
为了转向,对"0110"
之类的内容"12,9,47"
map
,我们需要arr
超过num
。来自arr
的每个数字,
都应该position
binary
,1
position
arr.map((num, position) => num + (Number(binary[position]) ? "," : "")).join("")
位于(Number(binary[position]) ? "," : "")
:
binary
表达式0
将","
评估为指定位置的数字。如果它是 truthy ,即除0
以外的任何内容,则评估为""
,如果它是 falsy ,即["1", "2,", "9,", "4", "7"]
,则评估为"12,9,47"
。
因此中间数组看起来像JSON.parse("[" +
。所有这些都联合起来+ "]")
。
然后,[12, 9, 47]
... 2 ** (arr.length - 1)
将其视为一个数组进行处理和解析,因此变为Math.pow(2, arr.length - 1)
。由于这些步骤适用于每个二进制字符串,因此最终会得到最终结果。
{length: 2 ** (arr.length - 1)}
可以替换为new Array(2 ** (arr.length - 1))
。(Number(binary[position]) ? "," : "")
可以替换为["", ","][Number(binary[position])]
。MariaDB
可以由tmp
替换。在这种情况下,评估的数字将用作临时数组的索引。答案 2 :(得分:1)
您可以通过迭代数组并插入空格来进行递归方法,并使用递增的索引分叉调用相同的函数。
function combine(array) {
function fork(i, p) {
if (i === array.length) {
result.push(p);
return;
}
fork(i + 1, p + ' ' + array[i]);
fork(i + 1, p + array[i]);
}
var result = [];
fork(1, array[0].toString());
return result;
}
console.log(combine([1, 2, 9, 4, 7]));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 3 :(得分:0)
你可以使用下面的代码,使用3指针,
let arr = [1, 2, 9, 4, 7];
console.log(arr.join(','));
for(let diff=2;diff<=arr.length;diff++){
for(i=0,j=diff;arr.length>=i+diff;j++,i++){
var temp = [];
if(i>0)
temp.push(arr.slice(0,i).join(','));
temp.push(arr.slice(i,j).join(''));
if(j<arr.length)
temp.push(arr.slice(j,arr.length).join(','));
console.log(temp.join(','));
}
}