前言
分享三个关于c语言的求质数方法,质数就是只能被1和自身整除的数
一、依次遍历法
将质数标记为0,合数为1。
依次遍历法。顾名思义,这种方法是最容易想到的但也是计算量最大的,利用质数只能被1和自身整除的特性求出范围内的质数。
#include <stdio.h>
int main() {
int n = 15;
int mark[16] = {
1, 1, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
int c;
int j;
for (c = 2; c <= n; c++)
{
for(j = 2; j <= c - 1; j++)
{
if(c % j == 0)
{
mark[c] = 1;
break;
}
}
}
for (c = 2; c <= n; c++)
{
if(mark[c] != 1)
{
printf("%d\n",c);
}
}
return 0;
}
二、质数筛法
原理在于利用质数的倍数是质数。初始时,假设全部都是素数,当找到一个素数时,显然这个素数乘上另外一个数之后都是合数把这些合数都筛掉,即算法名字的由来。
#include <stdio.h>
int main() {
int n = 15;
int mark[16] = {
1, 1, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
int c;
int j;
for (c = 2; c * c <= n; c++)
{
if(mark[c] != 1)
{
for(j = 2;j <= n / c;j++)
{
mark[c * j] = 1;
}
}
}
for (c = 2; c <= n; c++)
{
if(mark[c] != 1)
{
printf("%d\n",c);
}
}
return 0;
}
三、线性筛法
仔细分析质数筛法能发现,这种方法会造成重复筛除合数,影响效率。
比如10,在i=2的时候,k=2x15筛了一次;在i=5,k=5x6 的时候又筛了一次。所以,也就有了快速线性筛法。利用了每个合数必有一个最小素因子。每个合数仅被它的最小素因子筛去正好一次。所以为线性时间。
#include <stdio.h>
int main() {
int n = 15;
int index = 0;
int prime[n];
int mark[16] = {
1, 1, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
int c;
int j;
for(int i = 2; i < n; i++)
{
//如果未标记则得到一个素数
if(mark[i] == 0){
prime[index++] = i;
}
//标记目前得到的素数的i倍为非素数
for(int j = 0; j < index && prime[j] * i < n; j++)
{
mark[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
break;
}
}
}
for (c = 2; c <= n; c++)
{
if(mark[c] != 1)
{
printf("%d\n",c);
}
}
return 0;
}