2014-04-25 198 views
0

是否可以擦除iterator_range中的元素?迭代器範圍擦除元素

像這樣的東西(遺憾的是這個代碼不工作):my_it的

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; 
    } 
} 

預計值的檢查值的和(my_it + 1)

點就是擺脫構造對象像vectormapstring

+0

爲什麼你需要一個範圍在這裏?因爲你畢竟開始和結束? void test_erase(my_it it,my_it end) – 4pie0

+0

我想這只是一個最小的例子來展示這個想法。 – Gorpik

+0

擺脫範圍也是很好的。重點不在於構建像'vector','map'或'string'這樣的對象, – Lecko

回答

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,

+0

非常感謝!我已經發現了這個想法,現在我能夠完成我的代碼 – Lecko

0

迭代器範圍只不過是一對基礎迭代器。

因此,您是否可以從底層容器中刪除而不會使對中的迭代器無效,這取決於底層容器。

通常,std::list將支持這一點,但不是例如。 std::vector