给定一组数字S
,如何找到这些数字的所有可能产品(具有任何或所有因素的多重性)低于给定的n
?
例如,给定S = {2, 3, 5, 7, 11}, n = 12
,排序后我想看:
{ 1, 2, 3, 2^2, 5, 2*3, 7, 2^3, 3^2, 2*5, 11, 3*2^2 }
如果S
的大小是已知的小常数,我可以使用:
int p,sum=0;
for(int i[0] = 0; p <= n; i[0]++){
for(int i[1] = 0; p <= n; i[1]++){
for(etc.){...
p = pow(S[0],i[0])*pow(S[1],i[0])*pow(...
// do what you wanted to with p here
// in my case:
for(int j = 0; j < SIZE_OF_I; j++){
if(i[j] > 0){ p *= S[i] - 1; p /= S[i]; }
}
sum += p;
}
}
}
但我需要它适用于任意大小的S
。直觉上,它感觉像递归问题,但我不知道如何开始。
我应该指出的一件事是Project Euler的是,所以我无法获得数学方面的帮助。
答案 0 :(得分:1)
您可以使用优先级队列系统地构建系列。
我的想法是始终在队列的顶部生成最小的元素,当你处理它时,将这个数字加到队列中乘以S中的所有因子。
伪代码:
Create a priority queue (min heap) q
Add 1 to q
set last=0
while q.top() <= n:
current = q.popHead()
if current == last:
continue
last = current
yield current
for each x in S:
q.add(x*current)
该算法将生成所有可以在S
中按元素升序排列的元素,并按升序排列。
改进建议:
set
确保没有任何元素插入到队列中,而不是使用我在此处提供的last
补丁。答案 1 :(得分:1)
如果您只需要最终产品,可以使用递归功能:
function prod(base[], n, limit) {
if (base.length > 0 && n <= limit) {
process(n)
for (i = 0; i < base.length; i++) {
prod(base[i:], n * base[i], limit)
}
}
}
这将处理产品,但不按顺序处理。这基本上是您的嵌套循环变体,表示为递归。一旦超过限制,递归就会停止。 (伪代码符号base[i:]
表示从i
元素到结尾的子数组。)
如果您需要有关使用的素因子和尊重指数的信息,您应该传递一个额外的指数数组,您必须为每个递归调用调整这些指数。