Skip to content

Instantly share code, notes, and snippets.

@alzobnin
Created February 17, 2021 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alzobnin/9c10fc62c7e7eed824b46cf44bd89cc1 to your computer and use it in GitHub Desktop.
Save alzobnin/9c10fc62c7e7eed824b46cf44bd89cc1 to your computer and use it in GitHub Desktop.

Разбор задачи NextToken

Условие

Вам надо написать функцию NextToken для выделения очередного токена в строке. Токеном считается последовательность символов до указанного символа-разделителя (или до конца строки).

Использоваться функция будет примерно так:

int main() {
    std::string_view sv = "Hello world and good bye";
    const char delimiter = ' ';
    std::string_view token;
    while (NextToken(sv, delimiter, token)) {
        // обрабатываем очередной token
        // например, печатаем его на экране:
        std::cout << token << "\n";
    }
}

Гарантируется, что входная строка не заканчивается на разделитель. Догадайтесь сами, какие аргументы должна принимать функция NextToken. Эта функция может менять первый аргумент (sv).

Решение

Первый аргумент функции имеет тип std::string_view: это не самостоятельная строка, а отсылка к подстроке какой-то другой строки. По условию задачи её можно изменять. Будем при каждом вызове функции сдвигать её к началу следующего токена. Для этого этот аргумент будем принимать по ссылке. Аналогично, поледний аргумент функции тоже изменяется (в него должен быть записан токен), поэтому он тоже должен быть принят по ссылке.

Заметим, что функция возвращает false, если токенов больше нет.

#include <string_view>

bool NextToken(std::string_view& sv, char delim, std::string_view& tok) {
    if (sv.empty()) {
        return false;
    }
    auto pos = sv.find(delim);
    if (pos != sv.npos) {  // разделитель найден
        tok = sv.substr(0, pos);  // вырезаем очередной токен
        sv.remove_prefix(pos + 1);  // сдвигаем sv за разделитель
    } else {
        tok = sv;
        sv.remove_prefix(sv.size());  // формально тут получится пустая строка
    }
    return true;
}

Такая функция не может отличить случай изначально пустой строки от случая последнего пустого токена в строке, заканчивающейся на разделитель. Однако по условию задачи это не важно.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment