素数求解方法及其优化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了素数求解方法及其优化相关的知识,希望对你有一定的参考价值。

题目:

    请实现一个函数,对于给定的整型参数N,依次打印出小于N的素数。



解法一:试除法


由素数的定义我们很自然的会想到如下代码:

#include <stdio.h>

void print_prime(int n)
{
	int i=0;
	for(i=2;i<=n;i++)
	{
		int j=0;
		for(j=2;j<i;j++)
		{
			if(0==i%j)
				break;	
		}
		if(j==i)
			printf("%d\t",i);
	}
}

int main()
{
	int num=0;
	scanf("%d",&num);
	print_prime(num);	
	return 0;
}

在上面的代码中,我们看到在判断素数时一直从2试除到n-1。这里从n/2之后的数到n-1的试除显然是多余的,比如某个数不能被3整除,必然不能被6整除。


优化1:

    试除的范围优化到[2,n/2],这样一下子就将工作量减少了一半,代码如下:

void print_prime(int n)
{
	int i=0;
	for(i=2;i<=n;i++)
	{
	        int j=0;
		for(j=2;j<=i/2;j++) //修改部分
		{
			if(0==i%j)
				break;	
		}
		if(j==(i/2+1))  //修改部分
			printf("%d\t",i);
	}
}


既然能将试除范围优化到[2,n/2],那么这个范围是不是还能优化呢?答案是可以的,在[2,n/2]这个范围里(√n,n/2]的试除也是多余的。因为因数是成对出现的,比如16可分解为:1和16 、2和8、4和4、8和2、16和1。这些因数里必然有一个小于等于4。所以只需试除小于等于√n的数就可以了。


优化2:

      试除范围优化为[2,√n],代码如下:

#include <stdio.h>
#include <math.h>

void print_prime(int n)
{
	int i = 0;
	for (i = 2; i <= n; i++)
	{
		int j = 0;
		for (j = 2; j <= sqrt(i); j++) //修改部分
		{
			if (0 == i%j)
				break;
		}
		if (j >sqrt(i))         //修改部分
			printf("%d\t", i);
	}
}

int main()
{
	int num = 0;
	scanf("%d", &num);
	print_prime(num);
	return 0;
}


上面所有的代码在找素数的时候是从2到n,在这个范围内除了2之外的偶数都不是素数,所以我们可以跳过这些偶数。


优化3

寻找素数时跳过偶数,这样工作量就少了一半。代码如下:

void print_prime(int n)
{
	int i = 0;
	if (n >= 2)
		printf("%d\t", 2);
	for (i = 3; i <= n; i+=2)
	{
		int j = 0;
		for (j = 2; j <= sqrt(i); j++)
		{
			if (0 == i%j)
				break;
		}
		if (j >sqrt(i))
			printf("%d\t", i);
	}
}


本文出自 “牛丽” 博客,请务必保留此出处http://15129279495.blog.51cto.com/10845420/1739802

以上是关于素数求解方法及其优化的主要内容,如果未能解决你的问题,请参考以下文章

求100以内素数的5中基本方法及其优化

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化

求解最短路的四个算法及其优化

C语言中素数的判断方法

素数的筛法