我有一个以下形式的数字的素数因子列表: int [] factors = {factor of factor,factor1,poweroffactor1,factor2,poweroffactor2,...};
我希望得到相当于动态嵌套for循环的东西,它将产生所有因子,其中for循环看起来像这样:
int currentpod = 1;
for(int i=0;i<factors[2];i++)
{
currentprod *= Math.Pow(factors[1],i);
for(int j=0;j<factors[4];j++)
{
currentprod *= Math.Pow(factors[3],i);
...
//When it hits the last level (i.e. the last prime in the list, it writes it to a list of divisors
for(int k=0;k<factors[6];k++)
{
divisors.Add(Math.Pow(factors[5],k)*currentprod);
}
}
}
不幸的是,由于currentprod没有足够的重置,这个代码会爆炸。 以下是我用来尝试完成此操作的实际代码:
public static List<int> createdivisorlist(int level, List<int> factors, int[] prodsofar,List<int> listsofar)
{
if (level == factors[0])
{
prodsofar[0] = 1;
}
if (level > 1)
{
for (int i = 0; i <= 2*(factors[0]-level)+1; i++)
{
prodsofar[level-1] = prodsofar[level] * (int)Math.Pow(factors[2 * (factors[0] - level) + 1], i);
listsofar = createdivisorlist(level - 1, factors, prodsofar, listsofar);
}
}
else
{
for (int i = 0; i <= factors.Last(); i++)
{
listsofar.Add(prodsofar[level] * (int)Math.Pow(factors[2 * (factors[0] - level) + 1], i));
if (listsofar.Last() < 0)
{
int p = 0;
}
}
return listsofar;
}
return listsofar;
}
原始论点是: level =因子[0] factors =上面指定格式的素因子列表 prodsofar [] =所有元素都是1 listsofar =一个空列表
我如何重置prodsofar以便它不会“爆炸”而只是做我概述的内容? 注意:作为测试,使用2310,在当前代码下,要添加的除数为负(int溢出)。
答案 0 :(得分:1)
这只是一个“生成所有组合”的问题。您可以使用自己喜欢的搜索引擎在C#中找到这样做的方法; here就是一个例子。
请注意,您需要将“使用k次的素数”映射到{p, p, p, ...
}(k次)。
答案 1 :(得分:1)
你想到的递归算法的想法是保留一个累积的除数列表。为此,下面的代码是如何做到的一个例子(保留你的符号:因为“除数”和“因子”意思完全相同,多个术语是不幸的):
public static List<int> divisors(int[] factors, List<int> foundfactors, int level)
{
if(level > factors[0]) return foundfactors;
int current = 1;
List<int> curpowers = new List<int>();
for(int i=0; i<factors[2*level]+1; ++i)
{
curpowers.Add(current);
current *= factors[2*level-1];
}
List<int> newfactors = new List<int>();
foreach(int d in foundfactors)
foreach(int n in curpowers)
newfactors.Add(d*n);
return divisors(factors, newfactors, level + 1);
}
用类似
的方式调用它 // 600 = 2^3 * 3^1 * 5^2
int[] pfactors = new int[] {3, 2,3, 3,1, 5,2};
List<int> foundfactors = new List<int> {1};
List<int> ds = divisors(pfactors, foundfactors, 1);
foreach(int d in ds) Console.WriteLine(d);
打印所有24个除数600。
答案 2 :(得分:0)
这与接受的答案类似 - 对于想要了解最新情况的人来说可能会更清楚......
def divisors_from_primes(primes, v = 1)
if primes.empty?
puts v
return
end
p = primes.keys.first
m = primes[p]
primes.delete(p)
0.upto(m) do |power|
divisors_from_primes(primes, v * (p**power))
end
primes[p] = m
end
/* 72 = 2**3 * 3**2 */
divisors_from_primes({ 2 => 3, 3 => 2})
所以在这个例子中(72),它基本上是一个递归版本:
0.upto(3) do |twopower|
0.upto(2) |threepower|
puts 2**twopower * 3**threepower
end
end