5

我的目标是尝试解决这个问题:Removing all empty elements in a vector from end。使用擦除删除成语。

std::vector<std::string>这个想法是从给定的字符串中删除从末尾开始的所有空元素(等于空白) 。当找到非空元素时,应停止删除元素。

例子:

vec = { " ", "B", " ", "D", "E", " ", " ", " " };

拆除后:

vec = { " ", "B", " ", "D", "E"};

这是我尝试的解决方案:

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

int main()
{
    std::vector<std::string> vec = { " ", "B", " ", "D", "E", " ", " ", " " };

    bool notStop = true;
    auto removeSpaceFromLast = [&](const std::string& element)-> bool
    {
        if(element != " " ) notStop = false;
        return ( (element == " ") && (notStop) );
    };

    vec.erase(
        std::remove_if(vec.rbegin(), vec.rend(), removeSpaceFromLast),
            vec.rend() );

    std::copy(vec.begin(), vec.end(), std::ostream_iterator<std::string>(std::cout,","));

    return 0;
}

这给了我一个错误:

no matching function for call to  std::vector<std::__cxx11::basic_string<char> >::erase(std::reverse_iterator<__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > > >, std::vector<std::__cxx11::basic_string<char> >::reverse_iterator)'|

然后我读到std::vector::erase()这里的工作:Does vector::erase not work with reverse iterators?

并更改了代码:

vec.erase(
    std::remove_if(vec.rbegin().base(), vec.rend().base(), removeSpaceFromLast),
        vec.rend().base() );

这次它编译了,但给了我输出=原始向量。

任何人都可以解释:

  1. 为什么会这样?
  2. 如果可能,我们该如何解决?
4

1 回答 1

5

您错过了对 的调用base()remove_if将从向量的末尾开始找到的所有空间移动到向量的开始部分(因为如果使用前向迭代器,它将从开头移动到末尾的空间)并返回指向 to 结束位置的迭代器-被擦除的序列(即要保留的空间的开始,因为我们颠倒了迭代器的含义),即:

" ", " ", " ", "B", " ", "D", "E"

然后,您必须从头开始擦除,即rend().base().

vec.erase(vec.rend().base(), 
          std::remove_if(vec.rbegin(), vec.rend(), removeSpaceFromLast).base()
);
于 2018-05-01T08:37:26.493 回答