为第二个范围中的重复项设置差异,替代remove_copy

时间:2011-04-28 12:37:07

标签: c++ stl

我有两个数组或向量,比如说:

  int first[] = {0,0,1,1,2,2,3,3,3};
  int second[] = {1,3};

我想摆脱第一组中的1和3, set_difference 只能摆脱这些值的第一次出现,但这不是我想要的。

我应该通过迭代第二个范围并使用 remove_copy 来执行此操作,并且每次都从第一个集合中删除一个条目。

在C ++中执行此操作的最佳方法是什么?

4 个答案:

答案 0 :(得分:1)

你应该编写简单的函数或函数,如果元素在true中,则返回second,否则返回false(我们称之为ok)。然后使用std::remove_ifstd::remove_copy_if

first.erase(std::remove_if(first.begin(), first.end(), ok));

P.S。认为firststd::vector<int>而不是数组。

答案 1 :(得分:1)

你确定set_difference不起作用吗? 25.3.5中的标准说

  

此部分定义所有基本集   对排序结构的操作。他们   也适用于包含多个集合   多个等价副本   元件。

set_difference的描述只是说它首先给你所有东西而不是秒,这就是你想要的。

答案 2 :(得分:1)

编写专门的set_difference:

template <typename InputIterator1, typename InputIterator2, typename OutputIterator>
OutputIterator set_difference_any( InputIterator1 first1, InputIterator1 last1,
                                   InputIterator2 first2, InputIterator2 last2,
                                   OutputIterator result )
{
  while ( first1 != last1 && first2 != last2 )
    if ( *first1 < *first2 ) {
      *result = *first1;
      ++first1;
      ++result;
    } else if ( *first2 < *first1 ) {
      ++first2;
    } else {
      ++first1;
      //++first2; // this is the difference to set_difference
    }
  return std::copy( first1, last1, result );
}

然后将其应用于问题:

#include "set_difference_any.h"
#include <boost/range.hpp>
#include <iterator>
#include <vector>

std::vector<int> result;
set_difference_any( boost::begin( first ), boost::end( first ),
                    boost::begin( second ), boost::end( second ),
                    std::back_inserter( result ) );

此算法是线性的(最大last1-first1 + last2-first2比较)

答案 3 :(得分:0)

一般解决方案,当second包含多个元素时:在std::set中生成unordered_set(或second个元素,然后循环遍历{ {1}},删除任何不是集合的内容。 (循环我的意思是firstforwhile,无论如何。)