隐藏的bug
先看代码:
#include <bits/stdc++.h>
using namespace std;
int shus(int m); //声明函数
int main() {
int n = 0, m;
cin >> n;
while (n--) {
cin >> m; //输入数据判断
shus(m);
}
return 0;
}
int shus(int m) {
int size = m; // 数据规模
int half = size / 2; //找出中间数
int sn = (int) sqrt(size); //求出可以除与sn的数
vector<bool> p(half, true); //定义一个bool类型的容器,大小为half,初始值为true
for (int i = 1; i < half; i++) {
p[i] = true;
}
for (int i = 0; i < sn; i++) {
if (p[i]) {
for (int k = i + i + 3, j = k * i + k + i; j < half; j += k) {
p[j] = false;
}
}
}
// 统计素数个数
int count = 0;
for (int i = 0; i <= half ; i++) {
if (p[i]) {
count++;
}
}
cout << count << "\n";
return count;
}
vector容器的初始化实际上只有第一个元素初始化为true,其他的没有所以我要用
for (int i = 1; i < half; i++) {
p[i] = true;
}
来对其进行初始。
其实也可以用:
vector<bool> p(half);
fill(p.begin(), p.end(), true);
c++中的fill()
fill(G[0],G[0]+6*4,520);填充数组
fill(p.begin(),p.end(),true);填充容器
然后就是算法的核心了:
for (int i = 0; i < sn; i++) {
if (p[i]) {
for (int k = i + i + 3, j = k * i + k + i; j < half; j += k) {
p[j] = false;
}
}
}
实现筛选素数的核心算法,称为埃拉托斯特尼筛法(Sieve of Eratosthenes)。
首先,外层循环遍历从0到sn(sqrt(m))的所有数,其中sn是m的平方根。这是因为如果一个数m能被大于其平方根的数整除,那么必定能被小于其平方根的数整除,所以只需要考虑小于等于平方根的数即可。
在外层循环中,对于每个p[i]=true(表示i+2是素数)的情况,内层循环将p[j](j=i+i+3)及其后的所有元素设置为false,表示它们不是素数。具体来说,内层循环的起始值k为i+i+3,j的计算方式是使用公式k * i + k + i,每次递增k,即j的值为k的倍数(除了初始值k本身)。通过这样的操作,将所有的非素数标记为false。
最终,外层循环结束后,vector p中为true的位置对应的数就是素数。
需要注意的是,由于vector<bool>的特殊性,不能直接使用p[i]来修改元素的值,而是使用位操作来实现。在这里,p[j] = false就是将j位置上的值设置为false。
这段代码的目的是统计从3到m之间的所有素数的个数,并输出结果。
本文作者:2c237c6
本文链接:https://www.cnblogs.com/27dCnc/p/18568690
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了