Недавно я был на техническом собеседовании по C ++, где мне дали небольшой код простой обработки строк, который предназначен для получения строки и возврата строки, состоящей из первых и последних n символов, а затем продолжить чтобы исправить любые ошибки, а также сделать эту функцию максимально эффективной, я предложил решение ниже, однако интервьюер заявил, что существует еще более быстрый и оптимальный способ:
Исходный код:
std::string first_last_n(int n, std::string s)
{
std::string first_n = s.substr(0,n);
std::string last_n = s.substr(s.size()-n-1,n);
return first_n + last_n;
}
Мой код:
bool first_last_n(const std::size_t& n, const std::string& s, std::string& r)
{
if (s.size() < n)
return false;
r.reserve(2 * n);
r.resize(0);
r.append(s.data(),s.data() + n);
r.append(s.data() + (s.size() - n), s.data() + s.size());
return true;
}
Сводка моих изменений:
Изменен интерфейс, чтобы принимать возвращаемую строку в качестве ссылки (при условии, что RVO и rvalue еще не доступны)
Удалены временные строки, создаваемые через substr
Передана входная строка как константная ссылка в порядке для временного создания экземпляра ввода
Исправлена ошибка «off-by-1» в строке last_n
Уменьшено количество касаний каждого символа до одного или двух раз (в случае перекрывающегося сценария)
Поставил чек в случае, если размер строки s меньше n, вернуть ложно при неудаче.
Предполагая, что разрешен только собственный C ++, есть ли другой способ сделать это более эффективно или оптимально?
Примечание 1: Исходный экземпляр входной строки не должен изменяться.
Примечание 2: Все решения должны пройти следующий тестовый пример, в противном случае они недействительны.
void test()
{
{
std::string s = "0123456789";
std::string r = first_last_n(10,s);
assert(r == "01234567890123456789");
}
{
std::string s = "0123456789ABC0123456789";
std::string r = first_last_n(10,s);
assert(r == "01234567890123456789");
}
{
std::string s = "1234321";
std::string r = first_last_n(5,s);
assert(r == "1234334321");
}
}