算法

关于素数算法总结

2011/3/22

本文参考地址:http://www.kuqin.com/math/20071231/3269.html

http://hi.baidu.com/sulipol/blog/item/c6dd6c171eb81258f2de3270.html

判断素数:时间复杂度O(sqrt(n)/2), 速度提高O((n-sqrt(n))/2).

bool isprime( int num )
{
	int i ;
	int sq;
	if (num <=1) return 0;

	sq= (int)sqrt( num );
	for (i = 2 ;i <= sq ; i++ )
	{
		if ( num % i == 0 )
		{
			break ;
		}
	}
	if ( i <= sq )
		return 0;
	else
		return 1 ;
}

快速查找和输出素数 打表法

#include<stdio.h>
#include<math.h>
两种打表比较,第二种内存脚省,但是时间可能比较长一点

#define N 100000

int a[N];
int s1[100000];

int main()
{
	int i,j,k,n;

	for(i=0;i<=N;i++)//初始化表一
		a[i]=1;

	n=(int)sqrt(N);//注意n!!!
	for(i=2;i<=n;i++)//表一进行打表
	{
		for(j=i+i;j<=N;j+=i)//素数的倍数不是素数原理
			a[j]=0;
	}

	k=1;
	for(i=2;i<=N;i++)//将表一的素数存入表二,打表完成
		if(a[i])
		{
			s1[k]=i;
			k++;
		}

		for(i=1;i<k;i++)
			printf("%d\t",s1[i]);

		return 0;
}

打表法二:
/*方法运用了奇数对相关知识 证明见算法下面*/
/*1.首先素数先排除2和3的倍数*/
/*2.对6*n-1和6*n+1进行判断是否为素数。判断过程为3.*/
/*3.将当前6*n-1和6*n+1对素数表s[]中的前1~sqrt(le)+1 个数进行mod运算,都不能mod尽的为素数,并存表*/
/*重复2.和 3.的步骤直到循环结束*/
#include<stdio.h>
#include<math.h>
#define N 1000

int s[N];

int main()
{
    int i,j,ls,n;
	int a,b,sign1,sign2;

	s[1]=2;//步骤1
	s[2]=3;
	ls=2;
    for(i=6;i<N;i=i+6)//步骤2
	{
		a=i-1;
		b=i+1;
		sign1=1;
		sign2=1;
		n=(int)sqrt(ls);
		for(j=1;j<=n+1;j++)//步骤3.
		{
			if(a%s[j]==0)
			{
				sign1=0;
				break;
			}
		}

		for(j=1;j<=n+1;j++)
		{
			if(b%s[j]==0)
			{
				sign2=0;
				break;
			}
		}

		if(sign1)//素数存表
		{
			ls+=1;
			s[ls]=a;
		}
		if(sign2)
		{
			ls+=1;
			s[ls]=b;
		}

	}

    for(i=1;i<=ls;i++)
		printf(" %d\t",s[i]);
	return 0;
}

首先,说一下奇数对的概念:

中间只隔一个数字的两个素数(素数除了2之外都是奇数啦)被称为奇数对,比如17和19,29和31等等。证明奇数对之间的数字总能被6整除(假设这两个素数都大于6)。现在证明没有由三个素数组成的奇数对。

(注* 网上关于微软面试题的奇数对的概念是有误的,大概为翻译过来的错误)

方法二证明:

假设p和p+2是两个大于6的素数,则中间那个数为p+1。p+1为偶数,可以被2整除。p, p+1, p+2是三个连续的自然数,其中必然有一个能被3整除(不用证明了吧)。由于p和p+2都是大于6的素数,所以这个能被3整除的数必定是p+1。所以p+1能够被6整除。

同样,如果p是奇素数,则p, p+2, p+4之间必定有一个能够被3整除,所以不存在由三个素数组成的素数对。