循环中所有带零的数组组合
All array combinations with zero in a loop
给出如下数组
[10, 10, 10, 50, 50, 100, 100, 100, 500, 500, 500, 1000, 1000, 1000, 5000]
我现在想循环输出这些数字与 0 的所有组合。每个数字可以单独出现,也可以与数组中的任何其他数字一起出现(其余应该为 0)。组合时应保持数字的原始位置。
原数组的数字应该保留,只能用零代替。
数组的大小始终保持不变。所以没有额外添加零。所以不可能在增加数组长度的原始数组的数字之间插入零。
并且示例输入有三个 10,例如可以有第一个 10,然后是 0,然后再是 10。
组合的生成顺序没有要求。
我只是想用下面的例子来阐明我的想法。
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 10, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 10, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
这里进行的最佳方式是什么?
该任务实际上转化为生成 15 个二进制数字的二进制数,其中 0 表示“生成 0”,1 表示“从该位置的输入复制数字”。
很明显,有 215 种组合,因为这是使用 15 位可以产生的数字的数量。
因此 JavaScript 中的实现可能是:
let input = [10, 10, 10, 50, 50, 100, 100, 100, 500, 500, 500, 1000, 1000, 1000, 5000];
let quit = 20; // For demo purpose, let's stop after 20 outputs...
let count = Math.pow(2, 15); // Total number of combinations
for (let i = 0; i < count; i++) { // For each combination
let combi = []; // Create new empty array
for (let bit = 0, bits = i; bit < 15; bit++, bits >>= 1) {
// Depending on bit, either append 0 or the input to the array
combi.push(bits & 1 ? input[bit] : 0);
}
console.log(...combi); // Output all values in the array
if (quit-- < 0) break; // For this demo only
}
给出如下数组
[10, 10, 10, 50, 50, 100, 100, 100, 500, 500, 500, 1000, 1000, 1000, 5000]
我现在想循环输出这些数字与 0 的所有组合。每个数字可以单独出现,也可以与数组中的任何其他数字一起出现(其余应该为 0)。组合时应保持数字的原始位置。
原数组的数字应该保留,只能用零代替。
数组的大小始终保持不变。所以没有额外添加零。所以不可能在增加数组长度的原始数组的数字之间插入零。
并且示例输入有三个 10,例如可以有第一个 10,然后是 0,然后再是 10。
组合的生成顺序没有要求。
我只是想用下面的例子来阐明我的想法。
[10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 10, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 10, 10, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 10, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 50, 50, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
这里进行的最佳方式是什么?
该任务实际上转化为生成 15 个二进制数字的二进制数,其中 0 表示“生成 0”,1 表示“从该位置的输入复制数字”。
很明显,有 215 种组合,因为这是使用 15 位可以产生的数字的数量。
因此 JavaScript 中的实现可能是:
let input = [10, 10, 10, 50, 50, 100, 100, 100, 500, 500, 500, 1000, 1000, 1000, 5000];
let quit = 20; // For demo purpose, let's stop after 20 outputs...
let count = Math.pow(2, 15); // Total number of combinations
for (let i = 0; i < count; i++) { // For each combination
let combi = []; // Create new empty array
for (let bit = 0, bits = i; bit < 15; bit++, bits >>= 1) {
// Depending on bit, either append 0 or the input to the array
combi.push(bits & 1 ? input[bit] : 0);
}
console.log(...combi); // Output all values in the array
if (quit-- < 0) break; // For this demo only
}