使用Sets,C ++计算素数

时间:2015-12-22 19:17:36

标签: c++ pointers iterator set

我正在尝试使用集合来计算素数,但是当我进行计算时,我的迭代器会随机跳跃。

我正在尝试将此方法实现为N = 10的值。

  

选择一个整数n。此函数将计算所有素数   到了首先将1到n中的所有数字插入到集合中。然后擦掉所有   2的倍数(2除外);也就是说,4,6,8,10,12 ......清除所有   3的倍数,即6,9,12,15 .......上升到sqrt(n)。该   剩下的数字都是素数。

当我运行我的代码时,它会删除1然后pos跳转到4?我不确定为什么会发生这种情况,而不是它会转到值2,这是集合中的第二个值?

在我擦除迭代器指向的值之后会发生什么,迭代器指向的是什么,如果我将它推进到哪里前进?

以下是代码:

set<int> sieveofEratosthenes(int n){ //n = 10

    set<int> a;
    set<int>::iterator pos = a.begin();

//generate set of values 1-10
    for (int i = 1; i <= n; i++) {
        a.insert(i);
        if(pos != a.end())
            pos++;
    }

    pos = a.begin();

    //remove prime numbers
    while (pos != a.end())
    {
        cout << "\nNew Iteration \n\n";

        for (int i = 1; i < sqrt(n); i++) {
            int val = *pos%i;

            cout << "Pos = " << *pos << "\n";
            cout << "I = " << i << "\n";
            cout << *pos << "/" << i << "=" << val << "\n\n";

            if (val == 0) {
                a.erase(i);
                }
            }
        pos++;
    }
    return a;
}

2 个答案:

答案 0 :(得分:5)

你的实现是错误的,因为它试图将筛选算法与尝试除数的直接算法结合起来,并且它没有成功。你不需要测试可分性来实现筛子 - 实际上,这是算法之美的主要贡献者!你甚至不需要乘法。

a.erase(1);
pos = a.begin();
while (pos != a.end()) {
    int current = *pos++;
    // "remove" is the number to remove.
    // Start it at twice the current number
    int remove = current + current;
    while (remove <= n) {
        a.erase(remove);
        // Add the current number to get the next item to remove
        remove += current;
    }
}

Demo.

答案 1 :(得分:0)

当擦除循环内的元素时,你必须小心索引。例如,当您擦除位置0处的元素时,则下一个元素现在位于位置0.因此,循环应如下所示:

    for (int i = 1; i < sqrt(n); /*no increment*/) {
        /* ... */
        if (val == 0) {
            a.erase(i);
        } else {
            i++;
        }
    }

实际上,在擦除元素时,还必须注意集合的大小正在缩小。因此,您最好使用迭代器:

    for (auto it = a.begin(); i != a.end(); /*no increment*/) {
        /* ... */
        if (val == 0) {
            a.erase(it);
        } else {
            it++;
        }
    }

PS:以上并不完全是你需要的筛子,但它应该足以证明如何擦除元素(我希望如此)。