• 素数判断


    介绍

        素数又称质数,既只能被1和它本身除尽的自然数。也就是说素数只有1和它本身两个约数,它只能表示为1和它本身的乘积。

    原理

        使用一个for循环分别将需要判断的数(number)和2到number-1进行取余运算,如余数为0则表示可以除尽。当number不能被2到number-1的任何一个数除尽的时候,则number为素数,否则则不为素数。

    void main()
        {
           int i = 0;
         int a[10] = {5,4,9,8,7,6,0,1,3,2}; // 也可以是用scanf方法得到需要判断的数
         for(i = 0; i < 10; i++)
         {
         if(judgeprime(a[i])) // 调用素数判断函数
         printf("%d是素数. ", a[i]);
         else
         printf("%d不是素数. ", a[i]);
         }
        }

    算法1 复杂度O(n*log(n))

    #include <iostream>
    using namespace std;
      
    bool isPrime(int nr)
    {
        for (int d = 2; (d * d) < (nr + 1); ++d){
            if (!(nr % d)){
                return false;
            }
         }
        return true;
    }
      
    int main (int argc, char * const argv[])
    {
        for (int i = 0; i < 50; ++i){
            if (isPrime(i)){
                cout << i << endl;
            }
        }
    }

    算法2 复杂度O(n(log(logn)))采用排除法的方式

    示例:打印30以内的质数

    一、初始化如下列表。

     2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    二、把第一个数(2)取出来,去掉所有可以被2整除的数。

     2  3     5     7     9    11    13    15    17    19    21    23    25    27    29

    三、取第二个数(3),去掉所有可以被 3整除的数。

     2  3     5     7          11    13          17    19          23    25          29

    四、取第三个数(5),因为4已经被去除了,再去掉所有可以被5整除的数。

     2  3     5     7          11    13          17    19          23                29

    接下来的数是7,但是7的平方是49,其大于了30,所以我们可以停止计算了。剩下的数就是所有的质数了。

    算法3.O(log(n))或是O(1)的时间复杂度

    把质数事先就计算好,放在一个文件中,然后在程序启动时(注意是在启动时读这个文件,而不是运行时每调用一次就读一次文件),读取这个文件,然后打印出来就可以了。如果需要查找的化,二分查找或是hash表查找将会获得巨大的性能提升。

    算法4。

    使用编译时而不是运行时

    template<int N, int D = N - 1>
    struct isPrime {
        enum {
            result = (N % D) && isPrime<N, D-1>::result
        };
    };
      
    template<int N>
    struct isPrime<N, 1> {
        enum {
            result = true
        };
    };

    于是,通过这个模板,我们可以使用下面的代码来检查是否是质数:

    1
    2
    if (isPrime<3>::result)
        cout << "Guess what: 3 is a prime!";

    下一步,我们需要打出一个区间内的质数,所以,我们需要继续设计我们的print模板。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template<int N, bool ISPRIME>
    struct printIfPrime {
        static inline void print() {}
    };
      
    template <int N>
    struct printIfPrime<N, true> {
        static inline void print() {
            std::cout << N << endl;
        }
    };

    从上面的代码中,我们可以看到,我们的第一个实际是什么也没做,而第二个有输出,注意第二个的模板参数中有一个true,其意味着那个质数的判断。于是我们就可以给出下面的代码来尝试着打印出一段区间内的质数:(请不要编译!!因为那会让编译器进入无限循环中,原因是printPrimes会不停地调用自己永不停止)

    1
    2
    3
    4
    5
    6
    7
    8
    template<int N, int MAX>
    struct printPrimes {
        static inline void print()
        {
            printIfPrime<N, isPrime<N>::result>::print();
            printPrimes<N + 1, MAX>::print();
        }
    };

    为了避免这个问题,你需要再加一个模板类,如下所示。这样当N变成MAX的时候,递归就结束了。

    1
    2
    3
    4
    5
    6
    template<int N>
    struct printPrimes<N, N> {
        static inline void print() {
            printIfPrime<N, isPrime<N>::result>::print();
        }
    };

    最后,让我们来看看最终的调用:

    1
    2
    3
    4
    5
    int main (int argc, char * const argv[])
    {
        printPrimes<2, 40>::print();
        return 0;
    }

    这个方法很NB,但是有两个问题:

    • 比较耗编译时间。
    • 不能在运行时输入MAX的值。


     

  • 相关阅读:
    是用VLC API将RTSP流convert为视频文件
    VLC命令行的应用
    OpenRTSP的使用
    (3两个例子)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
    寻找轮廓的中点
    (4程序框架)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
    (2环境架设)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
    (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
    初步实现GoQtTemplate
    特征提取算法的综合实验(多种角度比较sift/surf/brisk/orb/akze)
  • 原文地址:https://www.cnblogs.com/lqc1002000/p/2535334.html
Copyright © 2020-2023  润新知