【问题标题】:Iterate and erase elments from std::set从 std::set 迭代和擦除元素
【发布时间】:2011-03-22 11:04:10
【问题描述】:

我有一个std::set,我需要删除相似的相邻元素:

DnaSet::const_iterator next = dna_list.begin();
DnaSet::const_iterator actual = next;
++next;

while(next != dna_list.end()) // cycle over pairs, dna_list is the set
{
    if (similar(*actual, *next))
    {
        Dna dna_temp(*actual);  // copy constructor
        dna_list.erase(actual); // erase the old one
        do
        {
           dna_temp.mutate(); // change dna_temp
        } while(!dna_list.insert(dna_temp).second);  // insert dna_temp
    }
    ++actual;
    ++next;
}

有时程序无法退出主循环。我认为当我删除dna_list 中的最后一个元素时会出现问题。完成这项任务的正确方法是什么?

【问题讨论】:

    标签: c++ iterator set erase


    【解决方案1】:

    使用actual = next 而不是++actual

    一旦你删除了actual,它就是一个无效的迭代器,所以++actual 的行为会很奇怪。 next 应该保持不变,因此将 actual 分配给 next 应该可以工作。

    【讨论】:

      【解决方案2】:

      您最好的选择是创建一个使用similar() 谓词的比较函子。然后你需要做的就是用那个比较函子构造集合,你就完成了。集合本身会将两个相似的元素视为相同,并且只会让第一个元素进入。

      struct lt_different {
          bool operator()(int a, int b) {
              return a < b && !similar(a, b);
          }
      
      private:
          bool similar(int a, int b)
          {
              // TODO:when are two elements similar?
              const int EPSILON = 2;
              return abs(a - b) < EPSILON;
          }
      };
      
      // ...
      set<int> o;  // fill this set with your data
      
      // copy your data to a new set that rejects similar elements
      set<int,lt_different> s(o.begin(), o.end(), lt_different());
      

      您可以使用 set s:插入元素、删除元素、修改元素 -- 并且该集合本身将确保该集合中不存在两个相似的元素。

      也就是说,您也可以自己编写算法,如果只是为了另一种选择。从&lt;algorithm&gt; 看看std::adjacent_find()。它将找到两个连续相同元素的第一次出现;坚持那个位置。找到之后,从该点找到与这些元素不同的第一个元素。您最终会得到两个迭代器,它们表示一系列连续的相似元素。您可以使用集合的 erase() 方法来删​​除它们,因为它有一个需要两个迭代器的重载。

      起泡、冲洗、整套重复。

      【讨论】:

      • 如何实现您的第一个想法?我需要为集合的元素实现operator==?我做不到,因为相似的概念和平等的概念不同,我都需要。也许有办法告诉std::set 使用特定函数(不同于operator==)来确定两个元素是否重复?
      • 我用示例代码更新了答案。是的,只需将集合的构造函数传递给您自己的比较函数。
      猜你喜欢
      • 1970-01-01
      • 2011-02-21
      • 2014-01-04
      • 1970-01-01
      • 2011-07-13
      • 2013-04-22
      • 2014-06-11
      相关资源
      最近更新 更多