Получить последнее слово строки


Мы должны печатать в последнем слове данной строки. Как улучшить и оптимизировать этот код?

#include <iostream>

std::string get_last_word(const std::string& str)
{
    if (str.length() == 0)
    {
        std::cerr << "No string\n";
        return 0;
    }

    int len = str.length();
    int i = len - 1;
    while (i >= 0 && str[i] != ' ')
    {
        i--;
    }
    std::string last_word;
    for (int j = i + 1; j < len; j++)
    {
        last_word += str[j];
    }
    return last_word;
}

int main()
{
    std::string str;
    std::cout << "Enter string :\n";
    std::getline(std::cin, str);
    std::cout << "Last word :\n";
    std::cout << get_last_word(str);
    std::cout << std::endl;
}


1509
8
c++
задан 15 апреля 2018 в 07:04 Источник Поделиться
Комментарии
2 ответа

Будьте осторожны с типами. Например, ваша функция get_last_word должен возвращать строку, но в вашем случае ошибки возвращает 0. Если вы хотите возвратить пустую строку, используйте return "";

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

Если вы разрешили использовать все в стандартной библиотеке, взгляните на std::string::find_last_of в качестве замены для вашего первого цикла.

Аналогично, посмотрите на std::string::substr в качестве замены для второй петли. Строим строку по одному символу за раз не рекомендуется, потому что оно довольно неэффективным. Что-то вроде substr будет более эффективно, поскольку оно может, например, выделить все памяти необходимые строки на одном дыхании.

13
ответ дан 15 апреля 2018 в 07:04 Источник Поделиться

Глядя на код, кажется, что вы не изобретать колесо.
Смотрите ответ от @Иосии, для некоторых альтернатив использования стандартной библиотеки.
Предполагаю, что это не возможно по каким-то причинам, допустим, ее плохо реализовали, я бы улучшить некоторые мелкие вещи.

Прежде чем дать некоторые улучшения, убедитесь, чтобы измерить!
Этот код используется только один раз? Это только 1% времени? Пример кода только использовать? Чем не тратить время на это!

Добавить предпосылки

В настоящее время ваша функция принимает пустую строку.
Когда это произойдет, вы всегда получите сообщение об ошибке.
Если вы где-то хотите справиться с этим по-разному, она должна быть проверена дважды.
Или в случае, если вы знаете, это не может быть пустой, она все равно проверяется, когда не требуется.

Вместо этого, вы могли бы написать:

assert(!str.empty() && "An empty string should not be passed");

Если ваш конкретный пример, то вам придется выписать чек в функции main. Однако, в этом случае можно использовать альтернативный способ обращения с ним. Например:

std::string str;
do
{
std::cout << "Enter string :\n";
std::getline(std::cin, str);
} while (str.empty());

Выделение памяти

std::string может иметь короткие строки оптимизации. Хотя, для больших строк, это может выделить память. Если добавить символ за символом, это может перераспределить.

Чтобы предотвратить это перераспределение, вы можете зарезервировать строку:

last_word.reserve(str.size() + 1 /*Null terminator*/);

Приведенный выше код должен быть прекрасным для вектора, когда у вас есть хотя бы 1 элемент. Однако, как мы уже короткая строка оптимизации, это может выделить, а результат не требует.

last_word.резерв(длн - к); // для проверки на нуль-Терминатор.

Если действительно критическое для производительности, вы, возможно, захотите, чтобы проверить реализацию стандартной библиотеки, так как они позволили оставить больше символов, чем вы проходите. Таким образом, они могут добавить 1 для нуль-Терминатора. (с libstdc++ и MSVC сделать так, я читал)

Выходной аргумент

Для того, чтобы не воссоздать строку, вы можете манипулировать исходную строку.
С erase способ, вы можете (в объеме) удалить все предыдущие персонажей сразу.

Это будет работать, когда вам не нужен этот аргумент, однако, это может добавить ненужные накладные расходы, если вы делаете или не есть объект std::string экземпляр.

string_view

std::string_view был добавлен в последней версии с++, это будет вести себя как строка, хотя, не хранит контент в нем.
Возвращая string_view может предотвратить копирование персонажей в std::string. То же можно сказать и о входной аргумент.

Предупреждение: это подвержено ошибкам, в случае, если вы работаете с Вэнс.

10
ответ дан 15 апреля 2018 в 08:04 Источник Поделиться