Удаление всех пустых элементов в векторе с конца - PullRequest
0 голосов
/ 30 апреля 2018

Учитывая std::vector строк, каков наилучший способ удаления всех элементов, начиная с конца, которые являются пустыми (равно пустой строке или пробелу). Удаление элементов должно прекратиться, когда будет найден непустой элемент.

Мой текущий метод (работа в процессе) выглядит примерно так:

while (Vec.size() > 0 && (Vec.back().size() == 0 || is_whitespace(Vec.back()))
{
    Vec.pop_back();
}

где is_whitespace возвращает логическое значение, указывающее, является ли строка пробелом или нет

Я подозреваю, что мой метод будет изменять размер вектора на каждой итерации, и это неоптимально. Может быть, с некоторым алгоритмом это можно сделать за один шаг.

Ввод: {"A", "B", "", "D", "E", "", "", ""}

Желаемый результат: {"A", "B", "", "D", "E"}

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Поскольку я не нашел хорошего на первый взгляд дурака, вот простое решение:

// Helper function to see if string is all whitespace
// Can also be implemented as free-function for readablity and
// reusability of course
auto stringIsWhitespace = [](const auto &str)
{
    return std::all_of(
        begin(str), end(str), [](unsigned char c) { return std::isspace(c); });
};

// Find first non-whitespace string from the back
auto it = std::find_if_not(rbegin(Vec), rend(Vec), stringIsWhitespace);
// Erase from there to the end
Vec.erase(it.base(), end(Vec));

Обратите внимание на unsigned в лямбде из-за этой ошибки .

Живой пример благодаря @ Killzone Kid .

0 голосов
/ 30 апреля 2018

Вот лучший способ:

for (auto it = Vec.rbegin(); it != Vec.rend() && is_whitespace(*it); )
{
    it = Vec.erase(it);
}

Он начнется с конца и остановится, как только встретится непробельный символ или будет достигнут вектор начала, в зависимости от того, что наступит раньше. Обратите внимание, что я не увеличиваю итератор в цикле for.

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