Skip to content

Instantly share code, notes, and snippets.

@alzobnin

alzobnin/Join.md Secret

Last active January 28, 2021 14:30
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/a09956a582ee08943d27a424fbe98b71 to your computer and use it in GitHub Desktop.
Save alzobnin/a09956a582ee08943d27a424fbe98b71 to your computer and use it in GitHub Desktop.

Разбор задачи "Функция Join"

Условие

Вам требуется написать функцию Join со следующим заголовком:

std::string Join(const std::vector<std::string>& tokens, char delimiter);

Функция должна вернуть строку, полученную склейкой элементов вектора через указанный разделитель. Например, Join({"What", "is", "your", "name?"}, '_') должна вернуть строку "What_is_your_name?".

Сдайте в систему код функции с необходимыми директивами #include. Ваша функция будет протестирована с помощью нашей программы.

Решение

Будем идти по вектору и добавлять в ответ разделитель и очередной токен. Важно, чтобы разделители не оказались по краям - они должны быть только между токенами.

Студенты часто спрашивают, может ли в функцию передаваться пустой или одноэлементный вектор? Конечно, может! В этом случае, очевидно, надо вернуть пустую строку или строку из одного элемента вектора, соответственно.

#include <string>
#include <vector>

std::string Join(std::vector<std::string>& tokens, char delim) {
    std::string result;
    for (size_t i = 0; i != tokens.size(); ++i) {
        if (i > 0) {
            result += delim;
        }
        result += tokens[i];
    }
    return result;
}

Есть вариант решения, где разделитель добавляется в конце всегда, а потом - если строка оказалась непустой - удаляется из неё:

#include <string>
#include <vector>

std::string Join(std::vector<std::string>& tokens, char delim) {
    std::string result;
    for (const auto& token : tokens) {
        result += token;
        result += delim;
    }
    if (!result.empty()) {
        result.pop_back();
    }
    return result;
}

Этот вариант плох тем, что может привести к лишней реаллокации строки result из-за последнего разделителя. Ещё хуже будет написать result = result.substr(0, result.size() - 1) вместо result.pop_back(): это приведёт к копированию подстроки, хотя можно было бы просто выкинуть последний символ. Кстати, подумайте, почему вдруг версия с substr работает без if (!result.empty()).

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