【问题标题】:C++ set container can't erase odd numbers [duplicate]C ++集合容器无法擦除奇数[重复]
【发布时间】:2013-09-21 09:23:15
【问题描述】:

此程序要求用户输入一个数字,然后将所有数字存储到一个集合容器中,并将其包括在内。问题是我要擦除特定的数字,但我不能,因为每当我尝试擦除奇数时程序就会冻结(由下面的 NUMBER 表示)。当我擦除偶数时它工作正常。但是,我注意到如果我将 y 的初始值更改为偶数,我将无法擦除偶数。在这里,我将其设置为奇数。我做错了什么?

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

int main()
{
set<int>s;
set<int>::iterator cnt;
int n,x,y=1;
cout<<"Number: ";
cin>>n;
for(x=0;x<n-1;x++)
{
    s.insert(y);
    y++;
}
for(cnt=s.begin();cnt!=s.end();cnt++)
{
    if(*cnt==NUMBER)
    s.erase(cnt);
}
for(cnt=s.begin();cnt!=s.end();cnt++)
cout<<*cnt<<"\n";
return 0;
}

【问题讨论】:

  • 呃 - 这是 C++ 而不是 C,请把你的变量声明放在它们的用法附近,或者这样做:typedef set&lt;int&gt; MySet; MySet s; /* ... */ for(MySet::iterator cnt = s.begin(); cnt != s.end(); ++cnt)

标签: c++ set containers


【解决方案1】:

set::erase 的文档说“引用被函数删除的元素的迭代器、指针和引用无效。所有其他迭代器、指针和引用保持其有效性。”

for(cnt=s.begin();cnt!=s.end();cnt++)
{
    if(*cnt==NUMBER)
    s.erase(cnt);
}

只要您执行s.erase(cnt)cnt 就不再指代集合中的元素。因此,当您执行cnt++ 时,您试图使其指向“下一个元素”,但没有下一个元素。

一种可能的解决方案:

cnt = s.begin();
while (cnt != s.end())
{
    if (*cnt == NUMBER)
        s.erase(cnt++);
    else
        ++cnt;
}

【讨论】:

    【解决方案2】:

    std::set 有一个 erase,它采用键值而不是迭代器,因此您的整个删除过程可以简化为:s.erase(NUMBER);

    你也可以使用std::copy从集合中获取数据输出,所以你最终得到:

     s.erase(NUMBER);
     std::copy(s.begin(), s.end(),
               ostream_iterator<int>(cout, "\n"));
    

    或者,您可以在将输出从集合复制到标准输出时过滤掉不需要的值,例如:

    std::remove_copy(s.begin(), s.end(),  
                     ostream_iterator<int>(cout, "\n"), NUMBER);
    

    【讨论】:

      猜你喜欢
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 2011-09-23
      • 1970-01-01
      • 2020-12-21
      • 2023-04-07
      相关资源
      最近更新 更多