一个学弟的c++作业要求写一个搜索素数的程序。
休息时间写了一个,不保证最优,能看就行。
#include<iostream>
#include<time.h>
using namespace std;
bool* gen_primetable(uint32_t maxval);
int main()
{
start:
uint32_t n = 100000000;
cout << "最大值" << n << "..." << endl;
clock_t start, finish;
start = clock();
auto table = gen_primetable(n);
finish = clock();
double cost = (double)(finish - start) / CLOCKS_PER_SEC;;
cout << "耗时" << cost << "秒" << endl;
uint32_t count = 1;
for (size_t i = 0; i <= n; i++)
{
if (!table[i]) continue;
count += 1;
//cout << i << "是素数"<<endl;
}
cout << "找到了" << count << "个素数" << endl;
system("pause"); delete[] table;
}
// 生成一个用于标记素数的布尔值表
bool* gen_primetable(uint32_t maxval)
{
uint32_t size = maxval + 1;
bool* table = new bool[size](); // 初始化size个值为false的存储空间
auto limit = sqrt(maxval); // 限制访问范围
for (size_t i = 3; i <= maxval; i+=2) // 大于2的奇数才有可能是素数
table[i] = true;
for (size_t i = 3; i <= limit; i += 2) // 遍历
{
for (size_t j = pow(i,2); j <= maxval; j += i) // 去掉能被i整除的数
table[j] = false;
}
return table; // 返回结果
}
平板低压i7跑到100000000大概4秒左右,应该够用了。
解析
1、偶数能被2整除,直接忽略
2、能被除了自己和1之外的整数整除的数不是素数
3、%运算符在很多情况下能够靠位运算代替来提高速度
4、有太多种方法可以不去判断奇偶,尽量靠寻址简化
5、为了可读性再优化就是鸟语了,如果封装成模块那肯定再优化(哪来这么蛋疼的功能)
6、还是有不少重复访问的地方,都要访问到冒烟了
7、不值得写多线程,线程建立和同步需要时间,数量少的单线程早就算完了
8、你可以优化到汇编级别甚至fpga实现然而还是没什么巨大性能提升
9、vector在这里大材小用