当前位置:   article > 正文

c、c++关于质数||素数的求法_c++求质数的算法

c++求质数的算法

我们要求某个范围内的所有质数,当然最基本最重要的方法就是除一个数取余数在判断是否为0

一、最简单的粗暴的穷举法

 

  1. #include<iostream>
  2. #include<math.h>
  3. #include<time.h>
  4. #define max 100
  5. using namespace std;
  6. void main() {
  7. clock_t start, end;
  8. start = clock();
  9. int * prime = (int*)malloc(sizeof(int)*max);//记录所有素数的数组
  10. int count = 1;//素数的个数
  11. *prime = 2;//初值
  12. for (int i = 3; i <= max; ++i) {
  13. bool choice = true;//假设为质数
  14. for (int j = 2; j <i; ++j) {
  15. if (i%j == 0) {//不是质数
  16. choice = false;
  17. break;
  18. }
  19. }
  20. if (choice) {
  21. *(prime + count) = i;
  22. count++;
  23. }
  24. }
  25. free(prime);//释放素数的数组指针,避免内存泄漏
  26. end = clock();
  27. float time = (float)(end - start) / 1000;
  28. cout << "time is " << time << "s" << endl;
  29. cout << "count is " << count << endl;
  30. system("pause");
  31. }

 

 

 

二、循环范围由2~i-1变成2~sqrt(i)

 

 

 

至于为什么是sqrt(i)自己思考吧,数学问题

  1. #include<iostream>
  2. #include<math.h>
  3. #include<time.h>
  4. #define max 100
  5. using namespace std;
  6. void main() {
  7. clock_t start, end;
  8. start = clock();
  9. int * prime = (int*)malloc(sizeof(int)*max);//记录所有素数的数组
  10. int count = 1;//素数的个数
  11. *prime = 2;//初值
  12. for (int i = 3; i <= max; ++i) {
  13. bool choice = true;//假设为质数
  14. for (int j = 2; j <=sqrt(i); ++j) {
  15. if (i%j == 0) {//不是质数
  16. choice = false;
  17. break;
  18. }
  19. }
  20. if (choice) {
  21. *(prime + count) = i;
  22. count++;
  23. }
  24. }
  25. for (int i = 0; i < count; ++i) {
  26. cout << prime[i] << endl;
  27. }
  28. free(prime);//释放素数的数组指针,避免内存泄漏
  29. end = clock();
  30. float time = (float)(end - start) / 1000;
  31. cout << "time is " << time << "s" << endl;
  32. cout << "count is " << count << endl;
  33. system("pause");
  34. }

 

 

 

 

 


三、我们发现每次循环都调用sqrt函数比较慢,所以先把这个数赋给k,直接调用k就好了

 

  1. #include<iostream>
  2. #include<math.h>
  3. #include<time.h>
  4. #define max 10000000
  5. using namespace std;
  6. void main() {
  7. clock_t start, end;
  8. start = clock();
  9. int * prime = (int*)malloc(sizeof(int)*max);//记录所有素数的数组
  10. int count = 1;//素数的个数
  11. *prime = 2;//初值
  12. for (int i = 3; i <= max; ++i) {
  13. bool choice = true;//假设为质数
  14. int k = sqrt(i);
  15. for (int j = 2; j <= k ; ++j) {
  16. if (i%j == 0) {//不是质数
  17. choice = false;
  18. break;
  19. }
  20. }
  21. if (choice) {
  22. *(prime + count) = i;
  23. count++;
  24. }
  25. }
  26. free(prime);//释放素数的数组指针,避免内存泄漏
  27. end = clock();
  28. float time = (float)(end - start)/1000;
  29. cout << "time is " << time <<"s"<< endl;
  30. cout << "count is " << count << endl;
  31. system("pause");
  32. }

 

 

 

 

 

 

四、这步优化相对困难。我们知道,所有合数都能写成若干素数相乘的形式,故判断i数i是否为质数,只需要用i除以从2到sqrt(i)之间的质数就可以,不需要除以这个区间的合数。但是问题出现了,我们要记录所有小于i的质数,这就要用堆内存建立一个整型数组,数组长度为max(我在考虑是不是可以建一个更小点的,,,算了,比较懒,不想了)用来保存所有已经求过的质数,这步的关键还有就是默认好2是第一个质数。

 

 

  1. #include<iostream>
  2. #include<math.h>
  3. #include<time.h>
  4. #define max 100000000
  5. using namespace std;
  6. void main() {
  7. clock_t start, end;
  8. start = clock();
  9. int * prime =(int*) malloc(sizeof(int)*max);//记录所有素数的数组
  10. int count = 1;//素数的个数
  11. *prime = 2;//初值
  12. int tempmax = 0;//小于sqrt(i)的最大素数下标
  13. for (int i = 3; i <= max; ++i) {
  14. bool choice = true;//假设为质数
  15. int k = sqrt(i) + 1;
  16. for (int j = 0; j <=tempmax; ++j) {
  17. if(prime[tempmax] < k)tempmax++;
  18. if (i % prime[j] == 0) {//不是质数
  19. choice = false;
  20. break;
  21. }
  22. }
  23. if (choice) {//是质数
  24. *(prime + count) = i;
  25. count++;
  26. }
  27. }
  28. //for (int i = 0; i < count; ++i) {
  29. // cout << i<<"            "<<prime[i] << endl;
  30. //}
  31. free(prime);//释放素数的数组指针,避免内存泄漏
  32. end = clock();
  33. float time = (float)(end - start) / 1000;
  34. cout << "time is  " << time << "s" << endl;
  35. cout << "count is  " << count << endl;
  36. system("pause");
  37. }
clock_t start, end; start = clock(); int * prime =(int*) malloc(sizeof(int)*max);//记录所有素数的数组 int count = 1;//素数的个数 *prime = 2;//初值 int tempmax = 0;//小于sqrt(i)的最大素数下标 for (int i = 3; i <= max; ++i) { bool choice = true;//假设为质数 int k = sqrt(i) + 1; for (int j = 0; j <=tempmax; ++j) { if(prime[tempmax] < k)tempmax++; if (i % prime[j] == 0) {//不是质数 choice = false; break; } } if (choice) {//是质数 *(prime + count) = i; count++; } } //for (int i = 0; i < count; ++i) { // cout << i<<"            "<<prime[i] << endl; //} free(prime);//释放素数的数组指针,避免内存泄漏 end = clock(); float time = (float)(end - start) / 1000; cout << "time is  " << time << "s" << endl; cout << "count is  " << count << endl; system("pause"); }

 


这点东西做了一上午,哎,真是咸鱼。。。大二重新做人吧

 

 

 

关于速度的结果如下,可以看到每一步的优化是有效果的,而且在求较大范围的质数时更加明显

本文章可能存在很多不足,请多指点

 

2017 / 7 / 7

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/75341
推荐阅读
相关标签
  

闽ICP备14008679号