我写了下面的C代码来找出大数的最大引物因子,我的程序在运行时会一直执行。我试图通过指定范围为2 ^ 32-1的iBigNum
来调试它,然后它奏效了。
LONG64 iBigNum = 600851475143,iCurr=0,iLarge=0;
//600851475143
/*4294967295
4000000000
*/iCurr = iBigNum-1;
while(iCurr > 0 )
{
if(iBigNum % iCurr == 0){
iLarge=iCurr;
break;
}
iCurr--;
}
MsgPrintf(TEXT("CustomPrint"),TEXT("%d"),iLarge);
之间,LONG64
定义为basetsd.h
//
// The following types are guaranteed to be signed and 64 bits wide.
//
typedef __int64 LONG64, *PLONG64;
我在运行3.16GHz,4 GB RAM的Intel Core 2 Duo CPU上运行代码。这是预期的行为吗?有人能给我指点方向吗? 谢谢
答案 0 :(得分:3)
从顶部开始似乎是一个好主意,因为你需要找到最大的因素,但事实并非如此。最小可能因子是2,因此最大可能因子是n/2
。您花费了第一次n/2
,即300425737571次迭代。在你的情况下情况更糟,因为最小的因素是17。
不要试图聪明。从底部开始你的因子分解。当您找到一个因子时,将您的数字除以它,可能是几次,并存储最后一个因子。当你的号码是1时停止。
(如果你的数字是一个素数的平方,这个天真的方法仍然很糟糕,但平均来说,如果你只检查一个数字,它应该相当快。)
编辑:这是代码,它将以我上面描述的方式找到最重要的因素。它将在非素数下合理地运行,但在大型素数(479001599)上运行它在我的机器上大约需要4秒钟。 OP的原始输入量是原来的1000倍。
有了这个警告,请点击这里:
LONG64 max_fact(LONG64 iBigNum)
{
LONG64 maxFact = 1;
LONG64 i = 2;
while(iBigNum > 1)
{
while (iBigNum % i == 0){
iBigNum /= i;
maxFact = i;
}
if (i == 2) i = 3; else i += 2;
}
return maxFact;
}
答案 1 :(得分:2)
你的算法非常慢。这就是它似乎永远存在的原因。
iBigNum/2
你将无所事事,因为那里没有任何因素。我建议你尝试实现一个实际的分解算法。 Pollards-Rho实现起来非常简单,并且会在几分之一毫秒内对64位整数进行分解。
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
static inline intmax_t pollards_rho_randomiser(intmax_t x, intmax_t n) {
return ((x * x) - 1) % n;
}
static inline intmax_t gcd(intmax_t x, intmax_t y) {
while (y) {
intmax_t temp = y;
y = x % y;
x = temp;
}
return x;
}
intmax_t pollards_rho(intmax_t n) {
intmax_t x = 2, y = 2, d = 1;
while (d == 1) {
x = pollards_rho_randomiser(x,n);
y = pollards_rho_randomiser(y,n);
y = pollards_rho_randomiser(y,n);
d = gcd(abs(x-y), n);
}
if (d == n)
return 0;
else
return d;
}
size_t factorise(intmax_t * factors, intmax_t iBigNum) {
size_t num_factors = 0;
intmax_t factor;
while ((factor = pollards_rho(iBigNum))) {
// makes sure to split everything into primes
num_factors += factorise(factors + num_factors, factor);
iBigNum /= factor;
}
factors[num_factors++] = iBigNum;
return num_factors;
}
int compare(const void * a, const void * b) {
return *(intmax_t *)b - *(intmax_t *)a;
}
int main () {
intmax_t iBigNum = 600851475143;
intmax_t factors[200];
size_t num_factors = factorise(factors, iBigNum);
qsort(factors, num_factors, sizeof(*factors), compare);
printf("%" PRIiMAX " = %" PRIiMAX, iBigNum, factors[0]);
size_t i;
for (i = 1; i < num_factors; i ++) {
printf("* %" PRIiMAX, factors[i]);
}
printf("\n");
return 0;
}