迭代器范围擦除元素

时间:2014-04-25 11:08:56

标签: c++ algorithm boost stl iterator

是否可以从iterator_range中删除元素?

像这样的东西(不幸的是这段代码不起作用):

void test_erase(my_it it,my_it end){
boost::iterator_range<my_it> r(it,end); 
for(; it<end; it++){
    if(pred(my_it)){
        boost::erase(r,boost::iterator_range<my_it>(it,it));
        continue;
    }
}

pred检查my_it和(my_it + 1)

的值

重点是摆脱构建vectormapstring

等对象

2 个答案:

答案 0 :(得分:2)

尽管remove_if对一元谓词进行操作,但在任何其他n个参数谓词上扩展它并不困难。

例如,使用二进制谓词删除可以这样写:

template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {

    ForwardIt result = first;
    while ( first != last - 1) {
        if ( !p( *first, *( first + 1))) {
            *result = *first;
            ++result;
        }
        if( first == last - 1) return result;
        ++first;
    }
    return result;
}

但你必须满足你的需要。这一切都取决于你如何对待元素对,如果谓词返回true或者其中之一,你想要删除它们吗?只剩下或只是对吗?等...

用法:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

bool bp (int left, int right) { return ( left + right == 2); }
/*
 * 
 */
int main(int argc, char** argv) {

    int a[] = { 0, 2, 1, 3, 0, 2, 3, 2, 0, 3, 8};
    std::vector<int> v( a, a + 11);
    std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
    std::cout << std::endl;
    std::vector<int>::iterator it = removeif( v.begin(), v.end(), bp);
    std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
    v.erase( it, v.end()); std::cout << std::endl;
    std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
    return 0;
}

输出:

0,2,1,3,0,2,3,2,0,3,8,

2,1,3,2,3,0,3,2,0,3,8,

2,1,3,2,3,0,3,

http://ideone.com/8BcmJq


如果条件成立,此版本将删除这两个元素。

template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {

    ForwardIt result = first;
    while (first != last - 1) {
        if (!p(*first, *(first + 1))) {
            *result++ = *first++;
            *result++ = *first++;
        } else {
            if (first == last - 1) return result;
            ++first;
            ++first;
        }
    }
    return result;
}

0,2,1,3,0,2,3,2,0,3,8,

1,3,3,2,0,3,3,2,0,3,8,

1,3,3,2,0,3,

答案 1 :(得分:0)

迭代器范围只不过是一对底层迭代器。

因此,是否可以在不使对中的迭代器失效的情况下从底层容器中擦除,取决于底层容器。

一般来说,std::list会支持这一点,但不是std::vector