C ++ deque迭代到倒数第二个元素

时间:2017-04-07 06:39:02

标签: c++

我正在尝试迭代deque以排除最后一个条目。理想情况下,我会避免计算和比较长度,所以我尝试了

soup.find_all("p",{"class":"text-muted"},text=True,recursive=False)

但编译器抱怨没有匹配操作数,这似乎是可以理解的,因为我有一个反向迭代器和一个常规迭代器。是否有一种优雅的方法可以在最后一个避免计数的元素之前停止?像,偏移? 我也试过回来,但结果却是一个参考而不是迭代器,所以!=也不开心。

4 个答案:

答案 0 :(得分:5)

您可以在结束前使用dq.end() - 1来获取一个。

您还可以使用std::removestd::remove_if删除所需的项目,而不是自行完成工作。请注意,这基本上类似于分区操作 - 它返回一个迭代器,您要保留的所有内容都是从范围的开头到迭代器。您要删除的所有内容都在该迭代器之后,直到您作为输入提供的范围的末尾。

在这种情况下,您可以对此常规订单执行某些操作:

std::deque<int> vals { 1, 2, 3, 4, 5, 6, 7, 8};

// get an iterator one before the end of `vals`
auto end = vals.end()-1;

// remove the even items in the range (so all except `8`)
auto pos = std::remove_if(vals.begin(), end, 
    [](int v){ return v %2 == 0;} 
);

// erase the items we just "removed"
vals.erase(pos, end);

// show the result
for (v : vals)
    std::cout << v << ", ";

答案 1 :(得分:1)

来自 std::deque::erase

  

除非擦除的元素位于容器的末尾或开头,否则所有迭代器和引用都将失效,在这种情况下,只有迭代器和对擦除元素的引用才会失效。

这意味着,您无法使用迭代器迭代双端队列并删除一些元素。相反,请将std::remove_ifstd::deque::erase一起使用。

(未经测试,但你会得到一个想法)

std::deque<T> dq = /* ... */;
auto from = std::remove_if(dq.begin(), std::prev(dq.end()),
    [](decltype(dq)::const_reference, decltype(dq)::const_reference){ return cond(); }
);
dq.erase(from, std::prev(dq.end()));

答案 2 :(得分:0)

这个怎么样:

deque dq;
//fill it
for(int i = 0; i < dq.size() - 1; i++) //notice the "-1" to avoid reaching the last element
{
    if ( cond() ) 
    {
        dq.erase(dq.begin()+i);
        i--;
    } 
}

您可以使用deque访问operator[]个元素,因此dq[i]是双端队列的元素编号i

答案 3 :(得分:0)

使用it_end.base()

#include <iostream>
#include <deque>
#include <iterator>

using namespace std;

int main()
{
    deque<int> dq = { 0, 1, 2, 3,4, 5 };
    auto it_end = dq.rbegin(); it_end++;

    for (auto it = dq.begin(); it != it_end.base(); ++it) {
        cout << *it << " ";
    }

    cout << "\n";
    return 0;
}

输出:

0 1 2 3 4

有关base()函数如何为反向迭代器工作的一些详细信息,请参阅https://stackoverflow.com/a/10373912/12711