【问题标题】:Not able to understand the logic behind the code which is an optimisation problem of generating prime numbers between two given numbers无法理解代码背后的逻辑,这是在两个给定数字之间生成素数的优化问题
【发布时间】:2020-05-27 09:16:02
【问题描述】:

Peter 想为他的密码系统生成一些素数。帮助他!你的任务是生成两个给定数字之间的所有素数!

输入 输入以单行中的测试用例数量 t (t

输出 对于每个测试用例,打印所有质数 p,使得 m

示例 输入:

2
1 10
3 5

输出:

2
3
5
7

3
5

警告:大量输入/输出数据,请注意某些语言(但如果算法设计良好,大多数应该没问题)

我在谷歌上查找了上述问题的优化解决方案,这是代码。

#include <iostream>
#include <cmath>
#include <vector>
#include <set>
using namespace std;

int main() {
    vector<int> primes;
    primes.push_back(2);

    for (int i = 3; i <= 32000; i+=2) {
        bool isprime = true;
        int cap = sqrt(i) + 1;

        vector<int>::iterator p;
        for (p = primes.begin(); p != primes.end(); p++) {
            if (*p >= cap) break;
            if (i % *p == 0) {
                isprime = false;
                break;
            }
        }
        if (isprime) primes.push_back(i);
    }

    int T,N,M;

    cin >> T;

    for (int t = 0; t < T; t++) {
        if (t) cout << endl;

        cin >> M >> N;
        if (M < 2) M = 2;

        int cap = sqrt(N) + 1;

        set<int> notprime;
        notprime.clear();

        vector<int>::iterator p;
        for (p = primes.begin(); p != primes.end(); p++) {

            if (*p >= cap) break;
            int start;

            if (*p >= M) start = (*p)*2;
            else start = M + ((*p - M % *p) % *p); //not able to understand this logic.

            for (int j = start; j <= N; j += *p) {
                notprime.insert(j);
            }
        }

        for (int i = M; i <= N; i++) {
            if (notprime.count(i) == 0) {
                cout << i << endl;
            }
        }

    }
    return 0;
}

我无法理解上面的代码。请帮助我理解它。我只是不明白这个程序背后的逻辑(我知道 STL,只是想了解逻辑)。

【问题讨论】:

  • 将 M 向下舍入到 *p 的前一个倍数。

标签: c++ stl


【解决方案1】:

真的很简单。您预先计算范围内存在的所有素数。然后对于每个素数的倍数,除了第一个,你将数字标记为“非素数”。

您标记的行仅计算特定素数在 M 到 N 范围内的倍数的首次出现。

编辑:更多解释。

此方法通过首先搜索所有非素数来找到素数。剩下的是素数。

首先要计算所有“小”素数。然后对于每个小素数,它标记所有适合目标范围的倍数。为此,您需要首先计算此素数在您的范围内的第一次出现 - 这就是“开始”变量。基本上它是> = M的素数的第一个倍数。 当您有“开始”时,您只需通过将质数添加到当前数字来标记所有倍数,直到达到 N。

如果您仍然对“开始”的计算内容和方式感到困惑,请尝试考虑如何找到“x”,使得它是“x = A * y”和“x >= M”,您知道 A 和M,但不知道“y”。

我也认为这个算法可能有错误。因为它应该为“非素数”集中的每个值完成这个循环。但是,如果第一个未计算的素数总是 > N 可能没关系。

【讨论】:

  • 哦,但是仍然无法理解该表达式是如何产生的。你能详细解释一下整个for循环(标记语句所在的地方)吗?
  • 扩展解释
猜你喜欢
  • 1970-01-01
  • 2019-11-10
  • 2021-12-30
  • 2021-12-05
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
相关资源
最近更新 更多