• 【算法】普通方法和筛选法求素数


    素数指的是因子仅仅有1和本身的数(1不是素数),求解素数在数学上应用很广泛,而求解n以内的素数也是我们编程时常遇到的问题,在这个问题上,筛选法求解素数执行得很快。以下首先介绍怎样推断一个是不是素数,然后介绍用普通方法求n以内的素数,接着是筛选法求n以内的素数,最后是两种算法的执行时间比較

    推断一个数是不是素数

    算法思想:推断小于等于一个数的平方的全部大于1的整数是不是能整除这个数,假设能,则表明这个数不是素数;反之,则是素数。

    //推断一个数是否为素数 
    bool isPlain(int value){
        int m = sqrt(value);
        if (value < 2) return false;
        for (int i = 2; i <= m; i++){
            if ((value%i)==0){
                return false;
            }
        }
        return true;
    }

    普通方法求解n以内的素数

    算法思想:声明一个n大小的bool数组。初始值为false,然后从2開始推断一个数是否为素数。若是。则将其的布尔值定为true

    //普通法求素数
    bool* putong(int n){
        bool* value = new bool[n];
        for (int i = 0; i < n; i++)
            value[i] = false;
        for (int i = 2; i < n; i++){
            if (isPlain(i)){
                value[i] = true;
            }
        }
        return value;
    }

    筛选法求n以内的素数

    算法思想:找出小于等于n的开方的素数。然后将n内全部这些素数的倍数统统去掉,剩下的数就都是素数,也是通过布尔数组实现

    //筛选法求素数
    bool* shuaixuan(int n){
        bool* value = new bool[n];
        for (int i = 0; i<n; i++)
            value[i] = true;
    
        value[0] = false;
        value[1] = false;
    
        for (int i = 2; i <= sqrt(n); i++){
            if (value[i] && isPlain(i)){
                int c = 2;
                int j = i*c;
                while (j < n){
                    value[j] = false;
                    j = i*c++;
                }
            }
        }
        return value;
    }

    完整代码及执行结果

    下述代码分别调用了普通方法和筛选法,可循环输入n(按Ctrl + C结束),以供不同数据的測试,后面附了一张执行測试的结果图

    #include <iostream>
    using namespace std;
    #include <ctime>
    #include <math.h>
    #include <conio.h>
    //推断一个数是否为素数 
    bool isPlain(int value){
        int m = sqrt(value);
        if (value < 2) return false;
        for (int i = 2; i <= m; i++){
            if ((value%i)==0){
                return false;
            }
        }
        return true;
    }
    
    //普通法求素数
    bool* putong(int n){
        bool* value = new bool[n];
        for (int i = 0; i < n; i++)
            value[i] = false;
        for (int i = 2; i < n; i++){
            if (isPlain(i)){
                value[i] = true;
            }
        }
        return value;
    }
    
    //筛选法求素数
    bool* shuaixuan(int n){
        bool* value = new bool[n];
        for (int i = 0; i<n; i++)
            value[i] = true;
    
        value[0] = false;
        value[1] = false;
    
        for (int i = 2; i <= sqrt(n); i++){
            if (value[i] && isPlain(i)){
                int c = 2;
                int j = i*c;
                while (j < n){
                    value[j] = false;
                    j = i*c++;
                }
            }
        }
        return value;
    }
    
    int main(){
    
        int n;
        while (cin >> n){
    
            int start = clock();
            bool* value1 = putong(n);
            int end = clock();
            cout << "普通方法:" << end - start << endl;
    
            start = clock();
            bool* value2 = shuaixuan(n);
            end = clock();
            cout << "筛选法:" << end - start << endl;
    
            delete[] value1;
            value1 = NULL;
            delete[] value2;
            value2 = NULL;
        }
        _getch();
    }
    

    这里写图片描写叙述
    从图中可看出,n越大。筛选法对普通方法的性能就越好。

  • 相关阅读:
    比特币节点同步问题
    Vue用axios跨域访问数据
    vue之vue-cookies安装和使用说明
    vuejs目录结构启动项目安装nodejs命令,api配置信息思维导图版
    使用以太坊智能合约实现面向需要做凭证的企业服务帮助企业信息凭证区块链化
    将任意文件写入以太坊区块的方法,把重要事件,历史事件,人生轨迹加密记录到区块链永久封存
    Linux下几种重启Nginx的方式,找出nginx配置文件路径和测试配置文件是否正确
    php小数加减精度问题,比特币计算精度问题
    Fabric架构:抽象的逻辑架构与实际的运行时架构
    国外互联网大企业(flag)的涨薪方式
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5371520.html
Copyright © 2020-2023  润新知