[英]C prime factorization (loop failure?)
我一直在研究这段简单的代码1.5个小时,但没有发现错误。 我开始疯了;)
你们每个人只要有新的想法和观点,都可以给我一点提示,我可能在哪里出现错误? (我是C的新手)
问题是:该代码对于我输入并测试的大多数数字都可以正常工作,但是偶然地我发现了一个不起作用的数字:3486118(或55777888的整数倍),它适合于第一个循环,但是在因子2之后,它将变成一个无限循环。
这是我的代码:(非常感谢您的帮助)
// Program calculates prime factors of entered number and returns them
#include <stdio.h>
int main() {
long int num, num_cp;
long int product=1;
/*prime number array up to 100.000*/
long int prime[] = {2, 3, **[...cut out MANY numbers...]** 99971, 99989, 99991};
printf("Please enter a positive integer:\n");
scanf("%li", &num);//55777888 or 3486118 not working... why?
//copy the entered number to keep the original for comparison with "product" and "break;" if equal
num_cp=num;
printf("prime factorization of %li:\n\n", num);
for (int i=0; i<sizeof(prime); i++) {
if (num_cp%prime[i]==0) {
num_cp/=prime[i];
product*=prime[i];
if (product==num) {
printf("%li\n\n", prime[i]);
break;
}
printf("%li*", prime[i]);
//If prime factor found but "product" is still not equal to "num" reset loop counter "i" to -1 (==0 in next loop)
i=-1;
}
}
printf("END");
return 0;
}
“我一直在研究这段简单的代码1.5个小时,但没有发现错误。我开始发疯了;)”
别。 别管它。 走开,吃披萨。 在您最喜欢的电影前播放视频。 洗个澡。 力争在2048(或更高水平)上取得新的高分。 您的大脑陷入了车辙,您再也看不到代码了。 您只会看到您认为的代码。
当您精疲力尽时,然后-仅在此之后-返回并实际阅读您编写的代码。 不是您认为自己编写的代码,而是您实际编写的代码。 是的,它们是不同的。
55777888的主要因子是2·2·2·2·2·1743059,其中最后一个因子太大而无法包含在列表中。
您可以在代码中解决此问题:当乘积等于找到的素数乘积时, num_cp
为1。如果在用完素数列表后num_cp
大于1,则为num
。 如果num/num_cp
小于您检查的最大素数,则可以假定num_cp
的剩余值为素数。 如果不是,那么您会更早发现更多因素。
您可以通过在主循环后添加其他检查来解决此问题:
if (num_cp > 1) printf("%li\n\n", num_cp);
(如果long int
是系统上的64位数字,则您仍然不安全:剩余因素可能由数组中没有的几个数字组成。)
最后:重置for
循环计数器以使循环重新开始不是一个好主意。 它总是从头开始,并重新检查您已经检查过的素数。 而且这不是自然的程序流程,这使得它很难阅读。 我认为,使用while
循环而不是内部if
块会更自然。
编辑 :以说明:
#include <stdio.h>
int main() {
long int num;
/* prime number array up to 100.000 */
long int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
int nprime = sizeof(prime) / sizeof(*prime);
num = 55;
printf("%li == ", num);
for (int i = 0; i < nprime; i++) {
long int p = prime[i];
if (num <= 1) break;
while (num % p == 0) {
num /= prime[i];
printf("%li", p);
if (num > 1) printf(" * ");
}
}
if (num > 1) printf("%li", num);
printf("\n");
return 0;
}
注意事项:
i
,而是使用while
循环,它消耗了相同因子的所有重复。 如果素数p
不除数,则不输入while
循环,就像if
子句一样。 num
的副本并在整个过程中使用了num
,主要是为了消除混乱。 我还删除了该product
。 所有素因应乘以原始数的逻辑是好的。 但这也反过来起作用:将数字除以所有质数后,剩下的就是1。无论如何,我们必须对数字进行除法。 通过删除产品,我们必须仅跟踪一个变量,而不是两个变量。 break
条件移到最前面,因此我们早早发现了负数和0。 也就是说,您的编码方式没有错,在某些地方也许有点不寻常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.