zoukankan      html  css  js  c++  java
  • <编程>比较两种素数表生成算法+计算程序运行时间+通过CMD重定向测试程序

    最近学习加密算法,需要生成素数表,一开始使用简单的循环,从2开始判断。代码如下:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<vector>
     5 #include<iterator>
     6 #include<algorithm>
     7 #include<ctime>
     8 #include<cstring>
     9 usingnamespace std;
    10 bool isPrimeNumber(int num);
    11 void judgePrimeNumber(int range,vector<int>&primeNumberList);
    12 int main(void)
    13 {
    14     int range;
    15     vector<int> primeNumberListJ;
    16     while(cin){
    17         cin >> range;
    18         judgePrimeNumber(range, primeNumberListJ);
    19         for(unsignedint i =0; i < primeNumberListS.size(); i++)
    20             cout << primeNumberListJ.at(i)<< endl;
    21         primeNumberListJ.clear();
    22     }
    23     return 0;
    24 }
    25 bool isPrimeNumber(int num)
    26 {
    27     if(num <2)
    28         return false;
    29     for(int i =2; i * i <= num; i++){
    30         if(num % i ==0)
    31             return false;
    32     }
    33     return true;
    34 }
    35 void judgePrimeNumber(int range,vector<int>&primeNumberList)
    36 {
    37     for(int i =2; i <= range; i++)
    38         if(isPrimeNumber(i))
    39             primeNumberList.push_back(i);
    40 }
     
    后来想起以前在学C语言的时候看过了叫筛选法的算法生成素数表。
    筛选法又称筛法,具体做法是:先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。
    具体代码如下:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<vector>
     5 #include<iterator>
     6 #include<algorithm>
     7 #include<ctime>
     8 #include<cstring>
     9 usingnamespace std;
    10 bool isPrimeNumber(int num);
    11 void selectPrimeNumber(int range,vector<int>&primeNumberList);
    12 int main(void)
    13 {
    14     int range;
    15     vector<int> primeNumberListS;
    16     while(cin){
    17         cin >> range;
    18         selectPrimeNumber(range, primeNumberListS);
    19         primeNumberListS.clear();
    20     }
    21     return 0;
    22 }
    23 bool isPrimeNumber(int num)
    24 {
    25     if(num <2)
    26         return false;
    27     for(int i =2; i * i <= num; i++){
    28         if(num % i ==0)
    29             return false;
    30     }
    31     returntrue;
    32 }
    33 void selectPrimeNumber(int range,vector<int>&primeNumberList)
    34 {
    35     bool*numMap =newbool[range +1];
    36     memset(numMap,true,sizeof(bool)*(range +1));
    37     numMap[1]=false;
    38     for(int i =2; i <= range;){
    39         while(!numMap[i]&& i <= range)
    40             i++;
    41         for(int j = i + i; j <= range; j += i){
    42             if(!numMap[j])
    43                 continue;
    44             numMap[j]=false;
    45         }
    46         i++;
    47     }
    48     for(int i =1; i <= range; i++)
    49         if(numMap[i])
    50             primeNumberList.push_back(i);
    51     delete[] numMap;
    52 }
     
    之后好奇心来了,筛选法到底比原来的方法高效了多少呢?
    记得time.h里有有个clock()函数,可以返回程序运行到当前的时间,可以用它的计算两种算法的耗时。
    具体代码如下:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<vector>
     5 #include<iterator>
     6 #include<algorithm>
     7 #include<ctime>
     8 #include<cstring>
     9 usingnamespace std;
    10 bool isPrimeNumber(int num);
    11 void selectPrimeNumber(int range,vector<int>&primeNumberList);
    12 void judgePrimeNumber(int range,vector<int>&primeNumberList);
    13 int main(void)
    14 {
    15     int range;
    16     vector<int> primeNumberListS;
    17     vector<int> primeNumberListJ;
    18     clock_t beginTime;
    19     clock_t endTime;
    20     while(cin){
    21         cin >> range;
    22         beginTime = clock();
    23         selectPrimeNumber(range, primeNumberListS);
    24         endTime = clock();
    25         cout <<"select Time: "
    26             <<double(endTime - beginTime)/ CLOCKS_PER_SEC
    27            << endl;
    28         beginTime = clock();
    29         judgePrimeNumber(range, primeNumberListJ);
    30         endTime = clock();
    31         cout <<"judge Time: "
    32             <<double(endTime - beginTime)/ CLOCKS_PER_SEC
    33            << endl;
    34         primeNumberListS.clear();
    35         primeNumberListJ.clear();
    36     }
    37     return0;
    38 }
    39 bool isPrimeNumber(int num)
    40 {
    41     if(num <2)
    42         return false;
    43     for(int i =2; i * i <= num; i++){
    44         if(num % i ==0)
    45             return false;
    46     }
    47     return true;
    48 }
    49 void selectPrimeNumber(int range,vector<int>&primeNumberList)
    50 {
    51     bool*numMap =newbool[range +1];
    52     memset(numMap,true,sizeof(bool)*(range +1));
    53     numMap[1]=false;
    54     for(int i =2; i <= range;){
    55         while(!numMap[i]&& i <= range)
    56             i++;
    57         for(int j = i + i; j <= range; j += i){
    58             if(!numMap[j])
    59                 continue;
    60             numMap[j]=false;
    61         }
    62         i++;
    63     }
    64     for(int i =1; i <= range; i++)
    65         if(numMap[i])
    66             primeNumberList.push_back(i);
    67     delete[] numMap;
    68 }
    69 void judgePrimeNumber(int range,vector<int>&primeNumberList)
    70 {
    71     for(int i =2; i <= range; i++)
    72         if(isPrimeNumber(i))
    73             primeNumberList.push_back(i);
    74 }
    先输入100测试一下,结果如下:
     应该是测试数据太小了,直接上10000吧:
    会发现,但素数表越大,两者差距也越大。范围再大10倍的话,循环判断就卡了好就还没出时间。
     
    最后额外的,在写程序的时候,经常要测试,当测试数据比较简短的时候可以手动输入。当测试数据比较多的时候,可以保存到txt文本文件中,放到测试程序的所在的目录下。
     
    然后打开cmd命令,进入到测试程序所在的路径。
    键入
    1. coding.exe < in.txt
    结果如下:
     
     自动输入测试数据。
    注意尖括号的方向。
    另外一个方向的尖括号可以用于保存程序输出结果:
    1. coding.exe > out.txt
     在测试程序所在的目录下会自动生成out.txt。
     
    最后的最后,一个高级的写法,从文件中读取输入,把结果输出到文件中:
    1. type in.txt | coding.exe > out.txt
    不上图,自行尝试。
  • 相关阅读:
    关系数据库元数据处理类(一) 创建元数据实体
    常用通用简单文件上传功能
    基于NOPI的Execl模板转换类,直接将Execl模板转换对应的Entity
    CSS彻底研究(3)
    CSS彻底研究(2)
    CSS彻底研究(1)
    CLR via C#
    前端JS模版库kino.razor
    CLR via C#
    CLR via C#
  • 原文地址:https://www.cnblogs.com/foundkey/p/6020716.html
Copyright © 2011-2022 走看看