我的代码出了问题,我不知道是什么。 GCC在没有任何警告的情况下编译它,但在运行时没有输出任何内容。
我只是在学习c(这实际上是欧拉的问题3。找到最大的素数因子600851475143)。
这段代码出了什么问题?
#include <stdio.h>
int primeCheck(unsigned long input);
int main(){
//goal: find largest prime factor of 600851475143
unsigned long goal = 600851475143;
for(unsigned long i = 600851475142; i > 0; i--){
if(primeCheck(i) == 1 && goal%i == 0)
printf("\n%lu\n\n", i);
}
}
int primeCheck(unsigned long input){
for(unsigned long i = 2; i < input; i++){
if(input%i == 0)
return 0;
}
return 1;
}
答案 0 :(得分:0)
你的程序最有可能太长来执行。尝试较小的数字,杰瑞暗示验证你的程序。
您可能需要查看此帖子: Prime factorization for big numbers 以获得更好的算法。
答案 1 :(得分:0)
假设您正在使用正确大小的数据结构(已经有足够的讨论),您的程序肯定执行时间太长。
请注意,除非600851475143本身是素数,否则最大素数因子不能超过1/3(我们可以清楚地看到2当然不是一个因素)。这说的是,几乎没有数学,我已经可以告诉你,第一个for循环中的if语句将返回false超过4000亿次,并且你正在对每个语句进行素数检查 即可。我不在乎你使用什么算法;你不能快速进行4000亿的素性检查。即使你换掉它来利用短路,你也要进行4000亿次的可分性检查,这也是无效的。
由于这个是 Project Euler,我不会放弃它,但我会给出一个提示:假设你知道一些较小的素因子。您如何使用它来设置最大因子有多大的上限?
答案 2 :(得分:0)
OP的代码适用于64位unsigned long
,但需要很长时间。
问题:
primeCheck()
最多迭代i < input
而不是i <= isqrt(input)
。两者都可以工作,但只需要达到input
的平方根,代码就可以更快地完成 。不需要进一步测试。
通常,余数和商一起计算,因此通过对商进行测试,代码可以免费获得“关于平方根” - 除数何时变得小于商?
int primeCheck(unsigned long input){
unsigned long q = input;
// for(unsigned long i = 2; i < input; i++){
for(unsigned long i = 2; i <= q; i++){
if(input%i == 0) {
return 0;
}
q = input/i;
}
return 1;
}
主循环开始寻找比目标少1的因子。这将有效,但第一个可能的因素是isqrt(goal)
。这要快得多
int main() {
//goal: find largest prime factor of 600851475143
unsigned long long goal = 600851475143;
unsigned long goal_sqroot = (unsigned long) sqrt(goal);
// In case `double sqrt(double)` gave a too low `isqrt()` answer ...
if (goal/goal_sqroot > goal_sqroot) goal_sqroot = goal/goal_sqroot;
// for(unsigned long i = 600851475142; i > 0; i--){
for (unsigned long long i = goal_sqroot; i > 1; i--) {
if (primeCheck(i) == 1 && goal % i == 0)
printf("%llu\n", i);
}
}
unsigned long
可能只是32位。使用unsigned long long
获取更大的数字,例如600851475143,一个40位数字。
输出&lt; 2秒:
6857
1471
839
71
其他简化可能,这是一个开始。