查找素数

位工具

void setbit(int pos, unsigned char * flags)
{
    unsigned char on = 1 << (pos % 8);
    flags[pos / 8] |= on;
}

void unsetbit(int pos, unsigned char * flags)
{
    unsigned char on = ~(1 << (pos % 8));
    flags[pos / 8] &= on;
}

bool getbit(int pos, unsigned char * flags)
{
    if((flags[pos / 8] & (1 << (pos % 8))) > 0)
        return 1;
    return 0;
}
void FindPrimeNums(int n)
{
    int flags_occupy = (n + 1) / 8 + 1;
    unsigned char * flags = new unsigned char[flags_occupy];
    memset(flags, 0xFF, flags_occupy);

    int laste = sqrt(n);
    for (int i = 2; i <= n; ++ i)
        if (getbit(i, flags))
        {
            cout << i << "\t";
            if(i <= laste)
                for (int j = 2; j * i <= n; ++ j)
                    unsetbit(i * j, flags);

        }

    cout << endl;
    delete[] flags;
}

去掉平方判断

void FindPrimeNums2(int n)
{
    int flags_occupy = (n + 1) / 8 + 1;
    unsigned char * flags = new unsigned char[flags_occupy];
    memset(flags, 0xFF, flags_occupy);

    for (int i = 2; i <= n; ++ i)
        if (getbit(i, flags))
        {
            cout << i << "\t";
            for (int j = 2; j * i <= n; ++ j)
                unsetbit(i * j, flags);
        }
        cout << endl;
        delete[] flags;
}

测试

#include <iostream>
#include <vector>
#include<ctime>

using namespace std;

class CTimer
{
public:
    CTimer()
    {
        _start=clock();
    }

    ~CTimer()
    {
        _end=clock();
        cout<< float(_end - _start) / CLK_TCK <<endl;
    }
private:
    clock_t _start;
    clock_t _end;
};

int main()
{
    CTimer * pct = new CTimer;
    FindPrimeNums(20000000);
    delete pct;
    pct = new CTimer;
    FindPrimeNums2(20000000);
    delete pct;
    return 0;
}

测试结果:

去除打印时间,查找20000000以内的素数,排除平方根以上的候选数可以调高20%左右的时间。

如图:

时间: 2024-10-10 11:46:10

查找素数的相关文章

试探究一种查找素数算法

解题思路:构造链表,使用筛除法 例如:求10以内素数 链表初始化:2 3 4 5 6 7 8 9 10 进行第一轮筛选后:2 3 5 7 9 也就是用2后面的数去除2, 第二轮筛选后:2 3 5 7 也就是用3后面的数去除3, 第三轮筛选后:2 3 5 7 也就是用5后面的数去除5 第四轮筛选后:2 3 5 7 代码: #include <stdio.h> #include <stdlib.h> #define N 1e5 // over this it is so slowly

NYOJ 快速查找素数

快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N<=2000000) 但N为0时结束程序. 测试数据不超过100组 输出 将2~N范围内所有的素数输出.两个数之间用空格隔开 样例输入 5 10 11 0 样例输出 2 3 5 2 3 5 7 2 3 5 7 11 #include<cstdio> #include<cstdlib>

快速查找素数

快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N<=2000000) 但N为0时结束程序. 测试数据不超过100组 输出 将2~N范围内所有的素数输出.两个数之间用空格隔开 样例输入 5 10 11 0 样例输出 2 3 5 2 3 5 7 2 3 5 7 11 来源 经典题 上传者 路过这 素数打表.提交开始超时.改成c语言的就过了 #includ

快速查找素数 NYOJ 187

1 #include<stdio.h>//快速查找素数(187) 2 int a[2000001]; 3 int main() 4 { 5 int m,i,j; 6 for(i=2;i<=2000000;i++){ 7 if(a[i]==0){ 8 for(j=i+i;j<=2000000;j=j+i){ 9 a[j]=1; 10 } 11 } 12 } 13 while(scanf("%d",&m)&&m!=0){ 14 for(i=2

NYOJ--187--快速查找素数(筛选法,素数打表)

快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N<=2000000)但N为0时结束程序.测试数据不超过100组 输出 将2~N范围内所有的素数输出.两个数之间用空格隔开 样例输入 5 10 11 0 样例输出 2 3 5 2 3 5 7 2 3 5 7 11 1 /* 2 Name: NYOJ--187--快速查找素数 3 Copyright: ?2

高速查找素数

高速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 如今给你一个正整数N,要你高速的找出在2.....N这些数里面全部的素数. 输入 给出一个正整数数N(N<=2000000) 但N为0时结束程序. 測试数据不超过100组 输出 将2~N范围内全部的素数输出.两个数之间用空格隔开 例子输入 5 10 11 0 例子输出 2 3 5 2 3 5 7 2 3 5 7 11 来源 经典题 上传者 路过这 素数打表.提交開始超时.改成c语言的就过了 #incl

NYOJ 187 快速查找素数

快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N<=2000000) 但N为0时结束程序. 测试数据不超过100组 输出 将2~N范围内所有的素数输出.两个数之间用空格隔开 样例输入 5 10 11 0 样例输出 2 3 5 2 3 5 7 2 3 5 7 11 打一下表就可以了 #include<stdio.h> #include<m

关于素数的快速查找——素数筛选法

利用素数筛选法进行素数的快速查找.原理很简单,素数一定是奇数,素数的倍数一定不是素数.思路如下: 预定义N表示10000,即表示查找10000以内的素数,首先定义数组prime[]对N以内的数进行标记,奇数存为1,偶数存为0,最终实现结果为素数的prime值为1,因此将prime[2]赋值为1(2是素数).之后利用for循环,对N以内的奇数进行遍历(注意for循环的条件控制),for里用if判断是否为素数(奇数),若是,执行内部嵌套的for循环判断该奇数是否为素数,若是则标记为1,若不是则pri

Perl快速查找素数

查找N内的所有素数,首先想到的就是: 对整数N从2开始到sqrt(N),进行整除计算,能整除则计算N+1,然后循环.方法简单,但效率低下.1000,000内的素数个数: #!/usr/bin/perl -w use strict; my $num=1000001; my $count=0; while($num>1){ my $i=sqrt($num); my $j=2; for(;$j<=$i;$j++){ last if(0==$num%$j); } $count++ if($j>$