判断素数的几种方法思考
【】判断素数是经常遇到的问题,下面就总结几种方法
1、最简单的从2~sqrt(N)的方法(N>=2,下同)
2、筛选法
3、素数判断法
概念说明:
素数,又叫质数,指除了1和它本身外,没有其他因数。(如果你不知道什么叫因数,建议你去从小学2年级开始学习-_-!);
合数:自然就是除了1和它本身外有其他因数。
需指出一点,1既不是质数也不是合数。
因此,判断N是素数的简单而笨的方法就是看看N有没有因数。
1、最简单的方法:
该算法的思想就是用2~sqrt(N),依次去对N求余,只要有一个余数是0,则N是合数。举例如下:
>>CODE
/*-------------isPrimer.c-------------
*----------Date : 09-25-2005---------
*----------All Rights Shared---------
*----------test in C-Free3.5---------
*-----------------------------------*/
#include
#include
#include
void main(int argc, char* argv[])
{
int N, i, m,flag = 0;
if(argc < 2)
{
while(1)
{
printf("Please input a non-integer:");
if(scanf("%d", &N) != 1)
{
fflush(stdin);
continue;
}
break;
}
}
else
N = atoi(argv[1]);
m =(int) sqrt(N*1.0);
for(i = 2;i <= m; i++)
if(N % i ==0)
{
flag = 1;
break;
}
if(flag)
printf("%d is not a primer\n", N);
else
printf("%d is a primer\n", N);
system("pause");
}
注:以上代码判断不出1、2、3来。
上面的代码就是按照这个简单的思路来的,思路是简单了,但是方法效率是不高的。因为我们知道,一个数如果不能被2整除,那么也就不能被4、6、等所有的偶数整除。但是我们的程序在判断了2之后依然会去判断4、6等。所以我们可以把循环规则改变成先判断2,如果不能被2整除就从3开始判断所有的奇数。即:
>>CODE
if(N % 2 != 0)
{
for( i = 3; i <= m; i +=2)
//……此处省略了
}
else
// 合数
2、筛选法判断素数。
这个方法不是用来判断一个素数,而是所有素数的方法。方法的原理是:
QUOTE:http://www.math.utah.edu/classes/216/assignment-07.html
The goal of this assignment is to design a program which will produce lists of prime numbers. The method is based on the one discovered by Erastosthenes (276 - 196 BC). His method goes l ...
这段E文没什么难理解的,就是首先生成数组,然后从第一个开始依次标注它的倍数,然后从下一个没有被标注的开始,标注它所有的倍数,这样依次下去,最后没有被标注的都是素数。下面是代码:
>>CODE
/*----------------------------------------
*--------------筛选法--------------------
*---------------------------------------*/
#include
#include
void main(int argc, char* argv[])
{
int N, i, *m, j = 0,temp;
if(argc < 2)
{
while(1)
{
printf("Please input a non-integer:");
if(scanf("%d", &N) != 1)
{
fflush(stdin);
continue;
} /* end if*/
break;
} /*end while*/
} /* end if*/
else
N = atoi(argv[1]);
m = (int*)malloc(sizeof(int) * (N - 1));
// inital the arry
for(i = 0; i < N -1; i++)
*(m+i) = i+2;
while(1)
{
// find the start number-index
for(; j < N - 2;j++)
if(*(m+j) != 0){temp = *(m+j);break;}
if(j < N - 2)
{
for(i = j+1; i < N - 1; i++)
if(*(m+i) % temp == 0)
*(m+i) = 0;
} /* end if*/
else break;
j++;
} /* end while*/
printf("The primer is:");
for(i = 0; i < N-1; i++)
if(*(m+i) != 0)printf("%d,", *(m+i));
printf("\n");
free(m);
system("pause");
} /* end main */
当然这样占用的空间是相当大的。另外,其实可以省略所有的偶数。
3、素数判断法【简单方法】
考虑到这么一个现实:任何一个合数都可以表现为适当个素数的乘积的形式,所以我们只用素数去除要判断的数即可,比如要判断100以内的素数,只用2,3,5,7就够了,10000以内的数用100以内的素数判断足以。
>>CODE
/*------------------------------------------
*---------------------100以内的素数-------
*-----------------------------------------*/
#include
#include
void main(int argc, char* argv[])
{
int N, i, j = 0,size;
int a[] = {2,3,5,7};
if(argc < 2)
{
while(1)
{
printf("Please input a non-integer:");
if(scanf("%d", &N) != 1)
{
fflush(stdin);
continue;
} /* end if*/
break;
} /*end while*/
} /* end if*/
else
N = atoi(argv[1]);
size = sizeof(a) / sizeof(int);
printf("The primer is:");
for(i =2; i < N; i++)
{
for(j = 0; j < size; j++)
{
if(i == a[j])
printf("%d,", i);
if(i % a[j] == 0)
break;
}
if(j == size)
printf("%d,", i);
}
printf("\n");
system("pause");
} /* end main */
如果是超过了100就要补充a[]的元素,另外循环部分还要做适当改动(比如不用循环size次)。
【总结】:以上3种方法中以第3中效率最高,但是其适用性不高,只适合不大的数。当然,以上3中方法还都可以改进,以后再写。