要知道什么是‘递归’.|

2c237c6

园龄:1年4个月粉丝:2关注:0

隐藏的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 中国大陆许可协议进行许可。

posted @   2c237c6  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起