Удаление пустых элементов из вектора - PullRequest
2 голосов
/ 06 февраля 2020

Я пытаюсь удалить пустые записи из 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 l oop, чтобы найти пустые элементы и удалить их оттуда. Должен быть и метод STL, но не уверен, как он будет работать.

1 Ответ

4 голосов
/ 06 февраля 2020

Кажется, вы имеете в виду следующее

#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" 

Что касается вашего кода, то он неэффективен, потому что вы пытаетесь удалить каждый найденный элемент отдельно и это l oop, например

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

Вывод программы такой же, как показано выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...