【问题标题】:Deleting empty elements from vector从向量中删除空元素
【发布时间】:2020-05-22 20:39:17
【问题描述】:

我正在尝试从std::vector 中删除空条目。这是一个示例代码,但这里有问题。

#include <iostream>
#include <string>
#include<vector>
#include <cctype>

int main()
{
    std::vector<std::string> s1 = {"a"," ", "", "b","c","   ","d"};
    for (auto it = s1.begin(); it != s1.end() && isspace(*it); )
{
        it = s1.erase(it);
}

    std::cout<<"vector size = "<<s1.size();
    for (auto &i:s1) 
        std::cout<<i<<"\n";      

}

我正在运行for 循环来找出空元素并从那里删除。应该也有 STL 方法,但不确定它是如何工作的。

【问题讨论】:

  • isspace() 需要 int(历史上,但实际上是一个字符),但您提供了 std::string。那不兼容。您可以改为检查(*it == "" || *it == " ")
  • 您的for 循环尝试仅从vector 的开头删除“空”条目。一旦它遇到一个非“空”条目 - 它就会停止。
  • 当你认为“有问题”时,你应该想想为什么你认为有问题。它是否编译?有编译错误吗?如果不是,它的行为是否符合您的预期?你期望它的表现如何?它的行为如何?
  • std::remove_if 是您要找的。​​span>

标签: c++ string algorithm c++11 vector


【解决方案1】:

你的意思好像是下面这个

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

int main() 
{
    std::vector<std::string> v = { "a", " ", "", "b", "c", "   ", "d" };

    auto is_empty = []( const std::string &s )
    {
        return s.find_first_not_of( " \t" ) == std::string::npos;
    };

    v.erase( std::remove_if( std::begin( v ), std::end( v ), is_empty ), std::end( v ) );

    for ( const auto &s : v )
    {
        std::cout << "\"" << s << "\" ";
    }
    std::cout << std::endl;

    return 0;
}

程序输出是

"a" "b" "c" "d" 

至于你的代码效率低下,因为你试图分别删除每个找到的元素,例如这个循环

for (auto it = s1.begin(); it != s1.end() && isspace(*it); )
{
    it = s1.erase(it);
}

永远不能迭代,因为第一个元素不满足条件isspace(*it),而且是无效的。也就是说,您将 std::string 类型的对象提供给需要 char 类型(更准确地说是 int 类型)的对象的函数。

如果要使用C函数isspace那么程序可以如下所示。

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

int main() 
{
    std::vector<std::string> v = { "a", " ", "", "b", "c", "   ", "d" };

    auto is_empty = []( const std::string &s )
    {
        return std::all_of( std::begin( s ), std::end( s ), 
                            []( char c ) 
                            { 
                                return std::isspace( ( unsigned char )c );
                            } );
    };

    v.erase( std::remove_if( std::begin( v ), std::end( v ), is_empty ), std::end( v ) );

    for ( const auto &s : v )
    {
        std::cout << "\"" << s << "\" ";
    }
    std::cout << std::endl;

    return 0;
}

程序输出同上图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多