我编译了程序但是当我给出输入= 600851475143时没有结果。程序是找到最大的素因子(13195的素数因子是5,7,13和29.什么是最大的素数因子号码600851475143?) 有什么问题?
#include<stdio.h>
int isprime(unsigned long n){
unsigned long i;
for(i=2;i<n;i++){
if((n%i)==0){
return 0;
}
}
return 1;
}
int main(){
unsigned long n,i,lpf;
scanf("%ld",&n);
for(i=2;i<n;i++){
if(n%i==0){
if(isprime(i)==1){
lpf=i;}
}
}
printf("%ld",lpf);
return 0;
}
答案 0 :(得分:0)
你有一个for循环,其运行次数大致与你输入的数字相同,i
从2
变为n-1
。在for循环中,您调用一个函数,该函数大约运行i
次,这与循环中的i
相同。这意味着您的程序会进行n^2
数学计算,其中n
是您的输入。如果输入12位数字,n^2
是24位数字的大小,对于程序,需要花费大量时间进行10^24
计算。所以你的程序运行,它只是计算。
答案 1 :(得分:0)
正如其他人已经说过的那样:你不需要走完整条路。只要达到n
的平方根就足够了。每次找到因子时,您也可以减少#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ISPRIME(x) isprime(x)
//#define ISPRIME(x) isprime_wheel(x)
static int wheel[] = {
1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2,
4, 2, 4, 14, 4, 6, 2, 10, 2, 6, 6, 4, 2, 4, 6, 2, 10, 2, 4, 2, 12, 10, 2, 4, 2,
4, 6, 2, 6, 4, 6, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 6, 8, 6, 10, 2, 4, 6,
2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 6, 10, 2, 10, 2, 4, 2, 4, 6, 8, 4, 2, 4, 12,
2, 6, 4, 2, 6, 4, 6, 12, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 10, 2, 4, 6, 2,
6, 4, 2, 4, 2, 10, 2, 10, 2, 4, 6, 6, 2, 6, 6, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8,
4, 2, 6, 4, 8, 6, 4, 6, 2, 4, 6, 8, 6, 4, 2, 10, 2, 6, 4, 2, 4, 2, 10, 2, 10,
2, 4, 2, 4, 8, 6, 4, 2, 4, 6, 6, 2, 6, 4, 8, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4,
6, 6, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10, 2, 6, 4, 6, 2, 6, 4,
2, 4, 6, 6, 8, 4, 2, 6, 10, 8, 4, 2, 4, 2, 4, 8, 10, 6, 2, 4, 8, 6, 6, 4, 2, 4,
6, 2, 6, 4, 6, 2, 10, 2, 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 6, 6, 4,
6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 8, 4, 6, 2, 6, 6, 4, 2, 4, 6, 8, 4, 2, 4, 2, 10,
2, 10, 2, 4, 2, 4, 6, 2, 10, 2, 4, 6, 8, 6, 4, 2, 6, 4, 6, 8, 4, 6, 2, 4, 8, 6,
4, 6, 2, 4, 6, 2, 6, 6, 4, 6, 6, 2, 6, 6, 4, 2, 10, 2, 10, 2, 4, 2, 4, 6, 2, 6,
4, 2, 10, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2, 12, 6, 4, 6, 2, 4, 6, 2, 12,
4, 2, 4, 8, 6, 4, 2, 4, 2, 10, 2, 10, 6, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4,
2, 10, 6, 8, 6, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 6, 4, 6, 2, 6, 4, 2, 4,
2, 10, 12, 2, 4, 2, 10, 2, 6, 4, 2, 4, 6, 6, 2, 10, 2, 6, 4, 14, 4, 2, 4, 2, 4,
8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 12, 2, 12
};
int isprime_wheel(unsigned long n)
{
unsigned long isqrt = (unsigned long) (floor(sqrt(n)) + 1);
unsigned long start = 5, factor = 2;
int wlen = sizeof(wheel) / sizeof(int);
int next = 0;
if(n == 2){
return 1;
}
if ((n & 1) == 0) {
return 0;
}
if (isqrt * isqrt == n) {
return 0;
}
while (factor < isqrt) {
if (n % factor == 0) {
return 0;
}
factor += (unsigned long) wheel[next];
next++;
if (next == wlen) {
next = start;
}
}
return 1;
}
unsigned long primefactors(unsigned long n)
{
unsigned long start = 5, factor = 2;
unsigned long biggest = 0;
int wlen = sizeof(wheel) / sizeof(int);
int next = 0;
if (n == 1) {
return 0;
}
if (n == 2 || n == 3) {
return n;
}
while (factor <= n) {
while (n % factor == 0) {
biggest = factor;
n /= factor;
}
factor += (unsigned long) wheel[next];
next++;
if (next == wlen) {
next = start;
}
}
if (n > 1 && biggest == 0) {
return n;
}
return biggest;
}
int isprime(unsigned long n)
{
unsigned long i;
unsigned long isqrt = (unsigned long) floor(sqrt(n)) + 1;
for (i = 2; i < isqrt; i++) {
if ((n % i) == 0) {
return 0;
}
}
return 1;
}
#include <time.h>
int main()
{
unsigned long n, i, lpf = 0, wheelfactor = 0;
clock_t start,stop;
if(scanf("%lu", &n) != 1){
fprintf(stderr,"Must be a positive, small integer \n");
exit(EXIT_FAILURE);
}
start = clock();
wheelfactor = primefactors(n);
stop = clock();
printf("WHEEL Time %.10f seconds\n", (double) (stop - start) / CLOCKS_PER_SEC);
printf("WHEEL %lu\n",wheelfactor );
start = clock();
if (n == 1) {
puts("0");
goto END;
}
if (n == 2 || ISPRIME(n) == 1) {
printf("NAIVE %lu (n is prime, next print must show 0)\n", n);
goto END;
}
for (i = 2; i < n / 2 + 1; i++) {
if (ISPRIME(i) == 1 && n % i == 0) {
//printf("PRIME %lu\n", i);
lpf = i;
n /= i;
// n might be down to 2 and isprime(2) returns true
// but only odd primes are allowed at this point
if (ISPRIME(n) == 1 && n > lpf) {
//printf("ISPRIME %lu\n", n);
lpf = n;
}
}
}
END:
stop = clock();
printf("NAIVE Time %.10f seconds\n", (double) (stop - start) / CLOCKS_PER_SEC);
printf("NAIVE %lu\n", lpf);
return 0;
}
的值。
稍微快一点的方法虽然和天真版本一样复杂,但是使用方向盘。这里使用的轮子是11个粗略数字之间的距离(加上前面的素数和下一轮的偏移量)。
所有在一起:
11529215046068460
您可以尝试使用一些大型复合材料,例如:1152921123
来查看运行时间的差异,或者def function():
string = StringVar()
string.set("Hello I'm A.py")
更加极端且需要很多耐心 - 它可能需要一个几分钟。
答案 2 :(得分:0)
早些时候,我注意到我的原始解决方案:
600851475143仍然需要太长时间,所以现在是时候寻找了 完全不同的算法
对SO的搜索出现efficient ways of finding the largest prime factor of a number。
这是一个简单快速的解决方案@ under5hell在该页面上的答案:
var myTable = $('#myTable').DataTable();
myTable.row( ':eq(0)' ).edit( {
name: 'Edit first row name object'
} );
可以在几分之一秒内找到最大的素数因子600851475143:
<强>输出强>
#include <stdio.h>
#include <assert.h>
int main()
{
unsigned long long number;
assert(sizeof(number) * 8 >= 64); // make sure we've enough bits
scanf("%llu", &number);
for (unsigned long long divisor = 2; divisor < number; divisor++) {
if (number % divisor == 0) {
number /= divisor--; // decrement to remove multiples
}
}
printf("%llu\n", number);
return 0;
}
在您查询SO之前,故事的道德似乎是搜索SO!