使用集合计算素数,C++
Posted
技术标签:
【中文标题】使用集合计算素数,C++【英文标题】:Calculating Prime Numbers using Sets, C++ 【发布时间】:2015-12-22 19:17:35 【问题描述】:我正在尝试使用一个集合来计算素数,但是当我进行计算时,我的迭代器随机跳跃。
我正在尝试为 N=10 的值实现此方法。
选择一个整数 n。此函数将计算所有素数 到 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;
【问题讨论】:
埃拉托色尼筛法不使用任何形式的可分性测试。您可以在根本不知道任何算术的情况下手动执行它。 【参考方案1】:您的实现不正确,因为它试图将筛算法与尝试除数的简单算法结合起来,但没有成功。您不需要测试可除性来实现筛子 - 事实上,这是算法美观的主要贡献者!你甚至不需要乘法。
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.
【讨论】:
不错!while (pos != a.end() && (*pos) * (*pos) < n)
也将满足“上升到 sqrt(n)”的要求。
*pos++ 是不是先赋值给 current 然后再递增?
@user2076774 *pos++
的行为就像一个指针:它在迭代器pos
处产生当前值,然后将递增的值存储到迭代器中。【参考方案2】:
在循环中擦除元素时,您必须小心索引。例如,当您擦除位置 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:以上内容并不完全是您对筛子所需要的,但它应该足以演示如何擦除元素(我希望如此)。
【讨论】:
以上是关于使用集合计算素数,C++的主要内容,如果未能解决你的问题,请参考以下文章
黑马基础阶段测试题:创建一个存储字符串的集合list,向list中添加以下字符串:”C++””Java”” Python””大数据与云计算”。遍历集合,将长度小于5的字符串从集合中删除,删除成功(代码