给定一个数字N,一个所有因子的数组,一个数字K ...我们需要找到多种方式将N表示为K个因子的乘积,即 如果
N=64
K=3
arr = [1,2,4,8,16,32,64]
因为
,所以方式数为71x1x64=64
1x2x32=64
1x4x16=64
1x8x8=64
以此类推
答案 0 :(得分:1)
要从数组中获取长度为k
的组合,我们可以使用递归生成器:
function* combinations(array, k, i = 0, prepend = []) {
if(!k) {
yield prepend;
} else {
while(i < array.length)
yield* combinations(array, k - 1, i /*+ 1*/, prepend.concat(array[i++]));
}
}
(注释+1是为了排除重复项(1 * 1 * 1
),但OP似乎不希望这种行为)
因此,要获得所有组合,我们可以做到:
[...combinations([1, 2, 3, 4], 2)] // [1, 2], [1, 3] ...
现在我们只需要将它们相乘:
const multiply = array => array.reduce((a, b) => a * b);
并滤除N:
[...combinations(arr, K)].filter(el => multiply(el) === N).length
这将返回7
。
PS:是的,有更简便,更快速的方法,但是我有时只想使用一些罕见(但很酷)的语言功能:)
答案 1 :(得分:0)
这将创建一个具有所有非重复组合的2D阵列。
var n = 64
var factors = [1, 2, 4, 8, 16, 32, 64]
var rep = []
for (var f1 = 0; f1 < factors.length; f1++) {
for (var f2 = 0; f2 < factors.length; f2++) {
for (var f3 = 0; f3 < factors.length; f3++) {
if (factors[f1]*factors[f2]*factors[f3] == n && factors[f3] >= factors[f2] && factors[f2] >= factors[f1]) {
rep.push([factors[f1], factors[f2], factors[f3]])
}
}
}
}
console.log(rep.length) // Get the amount of combinations
答案 2 :(得分:0)
其中a1,a2,.. ax是N的素数。我们可以将该公式进一步扩展为:
为了产生问题所需的K因子,我们必须从上面列出的素数中进行选择,任何素数都可以任意顺序选择,因此基本上可以在此公式中替换素数带有抽象符号的数字。
有多少种方法可以将N分解为K个数的乘积?将这些下划线分为K个组的方式也很多-每个K个数字一个组。对于第一个下划线,有K种将其分配给组的可能性;类似地,每个下划线都有K个可能性。总的来说,可能性是
[这基本上是一个分区问题:我们将b1 + b2 + .. + bx项拆分为K套]
现在唯一剩下的问题是确定N分解为素因数。或者,甚至更好的是,直接确定b1 + b2 + ... + bx之和。
counter=0;
for(int i=2;i<square_root(N);i++)
if(N%i==0) //i is a divisor of N
{
int M=N;
while(M%i==0)
{
counter++;
M=M/i;
}
}