【问题标题】:removing last elements from vector until condition从向量中删除最后一个元素,直到条件
【发布时间】:2014-11-04 20:15:58
【问题描述】:

我遇到了一个问题,我需要删除向量的最后一个元素,直到满足某个条件(为了这个例子,让它元素不为零)

我写了这段代码,它可以解决问题 -

auto next = vec.rbegin();
while (next != vec.rend())
{
    auto current = next++;
    if (*current == 0)
        vec.pop_back();
    else
        break;
}

但我更愿意找到一个我可以使用的 stl 算法(我可以使用 find_if 然后擦除,但我想在我删除的元素中循环 一次...)

另外,恐怕我在这里调用了一些 UB,我应该担心吗?

【问题讨论】:

  • 您编写的循环将删除最后的 n 元素,其中 n 是整个向量中 0 的数量,而不是末尾的 0 数量。这是你的意思吗?
  • @MarkB,谢谢,我忘记了 else 子句。
  • @juanchopanza,这会循环最后一个元素不止一次

标签: c++ vector stl


【解决方案1】:

您的代码可以更简单:

while( !vec.empty() && vec.back() == 0 ) 
    vec.pop_back();

使用std::removestd::remove_if 将删除基于标准的所有元素,因此您应该使用std::find_if,正如弗拉德在他的回答中提供的那样。

【讨论】:

  • 你确定他们不能使用反向迭代器吗?
  • @NeilKirk 好问题。关于 find_first_of 的文档需要 ForwardIterator,不清楚 reverse_iterator 是否满足该要求,这会很奇怪(基于名称)
  • 这确实缩短了我的代码,谢谢。我还在寻找一些 stl 算法解决方案,所以我会等一下,如果没有出现,我会批准这个答案......
【解决方案2】:

这是一个例子。它使用擦除向量的通用习语

v.erase( std::remove( /*...*/ ), v.end() )


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

int main() 
{
    std::vector<int> v = { 1, 2, 3, 4, 5, 0, 0, 0 };

    v.erase( 
        std::find_if( v.rbegin(), v.rend(), 
        []( int x ) { return x != 0; } ).base(), v.end() );

    for ( int x : v ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

输出是

1 2 3 4 5

【讨论】:

  • 1 2 3 4 0 5 怎么样?
  • @Slava 这里的零不是最后一个元素。所以这个顺序不能改变。
  • 是的,我明白了,您发现第一个元素从末尾开始不等于 0。好主意。
  • 这是我最初的实现,但这导致我迭代最后一个元素两次(一次直到找到非零,一次擦除元素)
猜你喜欢
  • 2012-08-20
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
相关资源
最近更新 更多