我接受一个复合数作为输入。我想打印它的所有因素,也是这个数字的最大素数因子。我写了以下代码。它完全正常,直到数字51.但是如果输入任何大于51的数字,则显示错误的输出。我怎样才能纠正我的代码?
#include<stdio.h>
void main()
{
int i, j, b=2, c;
printf("\nEnter a composite number: ");
scanf("%d", &c);
printf("Factors: ");
for(i=1; i<=c/2; i++)
{
if(c%i==0)
{
printf("%d ", i);
for(j=1; j<=i; j++)
{
if(i%j > 0)
{
b = i;
}
if(b%3==0)
b = 3;
else if(b%2==0)
b = 2;
else if(b%5==0)
b = 5;
}
}
}
printf("%d\nLargest prime factor: %d\n", c, b);
}
答案 0 :(得分:8)
这是一个扰流板,所以如果你想自己解决这个问题,请不要读这个:)。我将尝试按顺序提供提示,因此您可以按顺序阅读每个提示,如果需要更多提示,请转到下一个提示等。
提示#1: 如果除数是n的除数,则n /除数也是n的除数。例如,100/2 = 50,余数为0,所以2是100的除数。但这也意味着50是100的除数。
提示#2 给定提示#1,这意味着我们可以在检查素因子时从i = 2循环到i * i <= n。例如,如果我们检查数字100,那么我们只需要循环到10(10 * 10是<= 100),因为通过使用提示#1,我们将得到所有因子。那就是:
100 / 2 = 50, so 2 and 50 are factors
100 / 5 = 20, so 5 and 20 are factors
100 / 10 = 10, so 10 is a factor
提示#3 由于我们只关心n的素因子,只需找到n的第一个因子,称之为除数,然后我们可以递归地找到n /除数的其他因子。我们可以使用sieve方法并在找到它们时标记这些因素。
提示#4
C
中的示例解决方案:
bool factors[100000];
void getprimefactors(int n) {
// 0 and 1 are not prime
if (n == 0 || n == 1) return;
// find smallest number >= 2 that is a divisor of n (it will be a prime number)
int divisor = 0;
for(int i = 2; i*i <= n; ++i) {
if (n % i == 0) {
divisor = i;
break;
}
}
if (divisor == 0) {
// we didn't find a divisor, so n is prime
factors[n] = true;
return;
}
// we found a divisor
factors[divisor] = true;
getprimefactors(n / divisor);
}
int main() {
memset(factors,false,sizeof factors);
int f = 1234;
getprimefactors(f);
int largest;
printf("prime factors for %d:\n",f);
for(int i = 2; i <= f/2; ++i) {
if (factors[i]) {
printf("%d\n",i);
largest = i;
}
}
printf("largest prime factor is %d\n",largest);
return 0;
}
输出:
---------- Capture Output ----------
> "c:\windows\system32\cmd.exe" /c c:\temp\temp.exe
prime factors for 1234:
2
617
largest prime factor is 617
> Terminated with exit code 0.
答案 1 :(得分:3)
我认为你这样做是为了学习,所以我希望你不介意提示。
我首先在一个失败的数字上逐步执行你的算法。这会显示错误的位置吗?
答案 2 :(得分:2)
您需要重新编码,以便您的代码找到给定数字的所有素数,而不是仅计算素数2,3和5。换句话说,您的代码只能使用您的数字计算是素数或是2,3或5的倍数。但7,11,13,17,19也是素数 - 所以你的代码应该通过找到特定数字的所有因子并返回最大因素,不可分割。
答案 3 :(得分:0)
实际上,对于除最小数字之外的所有数据(下面,例如100,000),这是非常缓慢的。尝试找出数字的主要因素:
#include <cmath>
void addfactor(int n) {
printf ("%d\n", n);
}
int main()
{
int d;
int s;
int c = 1234567;
while (!(c&1)) {
addfactor(2);
c >>= 1;
}
while (c%3 == 0) {
addfactor(3);
c /= 3;
}
s = (int)sqrt(c + 0.5);
for (d = 5; d <= s;) {
while (c % d == 0) {
addfactor(d);
c /= d;
s = (int)sqrt(c + 0.5);
}
d += 2;
while (c % d == 0) {
addfactor(d);
c /= d;
s = (int)sqrt(c + 0.5);
}
d += 4;
}
if (c > 1)
addfactor(c);
return 0;
}
其中addfactor是某种宏,它将因子添加到素数因子列表中。获得这些后,您可以构建一个包含该数字所有因子的列表。
这比此处发布的其他代码段快得多。对于像10597959011这样的随机输入,我的代码将采用2000位操作加上1000次以重新构成除数,而其他输入则需要数十亿次操作。在这种情况下,它是“即时”和一分钟之间的区别。
答案 4 :(得分:0)
简化为dcp的答案(以迭代方式):
#include <stdio.h>
void factorize_and_print(unsigned long number) {
unsigned long factor;
for(factor = 2; number > 1; factor++) {
while(number % factor == 0) {
number = number / factor;
printf("%lu\n",factor);
}
}
}
/* example main */
int main(int argc,char** argv) {
if(argc >= 2) {
long number = atol(argv[1]);
factorize_and_print(number);
} else {
printf("Usage: %s <number>%<number> is unsigned long", argv[0]);
}
}
注意:这里有一个解析错误,没有正确获取argv中的数字。