<编程>比较两种素数表生成算法+计算程序运行时间+通过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
不上图,自行尝试。

 

posted on 2016-11-01 19:31  foundkey  阅读(493)  评论(0编辑  收藏  举报

导航