求素数

来自一个搜索小牛

目的:求N以内的所有质数
算法:英文名忘了,中文名是筛选法
原理:是从小到大把所有的质数的倍数剔除出去,直到N的开方为止
技巧:

1,很显然,当计算3的倍数时应该从9开始算起,也就是说计算任何一个质数的倍数时都从平方和算起
2,先把2的倍数算出来,这样以后再算其他质数P的倍数时,可以从平方和起一次加2*P,因为P是质数,所以是奇数,所以P*P+P是偶数,所以合理的大于P*P的下一个P的倍数是P*P+2*P,同理,以后依此加2*P

代码:

#include <conio.h>
#include <vector>
#include<iostream>
#include<iomanip>
using namespace std;
//---------------------------------------------------------------------------
void __fastcall FindPrimes(const unsigned int& num,vector<unsigned int>& vec)
{
 bool *numbers=new bool[num+1];
 numbers[2]=true;//true为质数
 for(unsigned int i=3;i<=num;i++)
     numbers[i]=i%2;
 unsigned int ininum=3;
 unsigned int t;
 while((t=ininum*ininum)<=num)
      {
      while(t<=num)//寻找倍数
           {
           numbers[t]=false;
           t+=ininum<<1;//乘2
           }
      while(!numbers[++ininum]);//寻找下一个质数
      }
 for(unsigned int i=2;i<=num;i++)
    {
    if(numbers[i])
       vec.push_back(i);
    }
 delete[] numbers;
}
//----------------------------------------------------------------------------

 

int main(int argc, char* argv[])
{
 vector<unsigned int> primes;
 
 FindPrimes(1000,primes);
 
 vector<unsigned int>::iterator vi=primes.begin();
 int format=0;
 for(;vi!=primes.end();vi++)
    {
     cout<<setw(4)<<*vi<<" ";
     format++;
     if(format%16==0)
        {
        cout<<endl;
        format=0;
        }
     }
 cout<<"找到质数"<<primes.size()<<"个"<<endl;
 getchar();
 return 0;
}


 

附:满详细的素数介绍以及另一个程序

简单介绍一下厄拉多塞筛法。厄拉多塞是一位古希腊数学家,他在寻找素数时,采用了一种与众不同的方法:先将2-N的各数写在纸上:

在2的上面画一个圆圈,然后划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数;现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于N的各数都画了圈或划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 N的素数。

这很像一面筛子,把满足条件的数留下来,把不满足条件的数筛掉。由于这种方法是厄拉多塞首先发明的,所以,后人就把这种方法称作厄拉多塞筛法。
在计算机中,筛法可以用给数组单元置零的方法来实现。具体来说就是:首先开一个数组:a[i],i=1,2,3,…,同时,令所有的数组元素都等于下标 值,即a[i]=i,当i不是素数时,令a[i]=0 。当输出结果时,只要判断a[i]是否等于零即可,如果a[i]=0,则令i=i+1,检查下一个a[i]。
筛法是计算机程序设计中常用的算法之一。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值