因式分解 1 到 10 7范围内的所有数字。使用对 Eratosthenes 筛的修改,您可以使用空间将所有数字从 1 分解到n
时间O(n*log n)
(我认为它更好一点,O(n*(log log n)²)
或者如此)O(n*log log n)
。比这更好的可能是创建一个仅包含最小素数的数组。
// Not very optimised, one could easily leave out the even numbers, or also the multiples of 3
// to reduce space usage and computation time
int *spf_sieve = malloc((limit+1)*sizeof *spf_sieve);
int root = (int)sqrt(limit);
for(i = 1; i <= limit; ++i) {
spf_sieve[i] = i;
}
for(i = 4; i <= limit; i += 2) {
spf_sieve[i] = 2;
}
for(i = 3; i <= root; i += 2) {
if(spf_sieve[i] == i) {
for(j = i*i, step = 2*i; j <= limit; j += step) {
if (spf_sieve[j] == j) {
spf_sieve[j] = i;
}
}
}
}
要n > 1
使用该筛子对数字进行因式分解,请查找其最小的素因数p
,确定其在因式分解中的多重性n
(通过递归查找,或者通过简单地除以直到p
不均匀地除剩余的辅因子,这取决于更快)和辅因子。当辅因子大于 1 时,查找下一个主因子并重复。
创建从素数到整数的映射
遍历两个数组,对于 中的每个数字N
,将其分解中的每个素数的指数添加到映射中的值,对于 中的数字D
,减去。
浏览地图,如果素数的指数为正,则输入p^exponent
数组N
(如果指数太大,您可能需要将其拆分为多个索引,对于较小的值,将多个素数合并到一个条目中 - 有 664579质数小于 10 7,因此数组中的 100,000 个插槽可能不足以存储每个出现的具有正确幂的质数),如果指数为负,则对D
数组执行相同操作,如果为 0,则忽略该质数。
然后将任何未使用的插槽N
或D
设置为 1。