Ответ
В C++ для строки типа std::string самый эффективный и идиоматичный способ — использовать алгоритм std::reverse из стандартной библиотеки. Он выполняет in-place разворот за линейное время O(n) и константную дополнительную память O(1).
#include <algorithm>
#include <string>
#include <iostream>
int main() {
std::string str = "Hello, World!";
std::reverse(str.begin(), str.end());
std::cout << str << std::endl; // Вывод: "!dlroW ,olleH"
return 0;
}
Почему это минимальные затраты:
- Время: O(n) — меньше нельзя, нужно посетить каждый символ.
- Память: O(1) — алгоритм использует два итератора и меняет символы местами, не создавая новую строку.
- Оптимизация: Реализация
std::reverseв стандартной библиотеке часто использует оптимизации для конкретного компилятора.
Для C-строк (массивов char) принцип тот же, но реализуется вручную:
#include <cstring>
void reverse_c_string(char* str) {
if (!str) return;
char* end = str + strlen(str) - 1;
while (str < end) {
std::swap(*str, *end); // или ручной обмен через временную переменную
++str;
--end;
}
} Ответ 18+ 🔞
А, ну вот, опять про разворот строки спрашивают. Ну, блядь, классика жанра, ебать мои старые костыли. Каждый второй джуниор на собеседовании с этим сталкивается, а потом в коде пишет какую-то дичь с созданием новой строки и конкатенацией в цикле, овердохуища памяти жрёт.
Так, слушай сюда, чувак. Всё проще, чем кажется. В C++ для std::string уже всё придумали за нас, умные дядьки. Не надо изобретать велосипед, который, кстати, будет кривой и на коленке собранный.
Самый правильный и быстрый способ — это взять и вызвать std::reverse. Это как взять и перевернуть бутерброд с колбасой — просто перекладываешь кусочки с одного края на другой, а не делаешь новый бутерброд из каждого кусочка хлеба отдельно, понимаешь?
Вот, смотри, как это выглядит в коде. Блоки кода я не трогаю, они святые.
#include <algorithm>
#include <string>
#include <iostream>
int main() {
std::string str = "Hello, World!";
std::reverse(str.begin(), str.end());
std::cout << str << std::endl; // Вывод: "!dlroW ,olleH"
return 0;
}
Вот и вся магия. Почему это оптимально? Да ёпта, потому что меньше никак! Алгоритм работает за O(n) — быстрее не получится, всё равно каждый символ ткнуть пальцем надо. А памяти он жрёт O(1), то есть практически ноль. Он просто берёт два итератора — один с начала, другой с конца — и меняет их местами, пока они не встретятся посередине. Никаких новых строк, никакого лишнего копирования. Красота!
А если у тебя вдруг старый добрый сишный массив char, то там, конечно, придётся немного покрутиться самому. Но принцип тот же — идёшь с двух концов и меняешь символы, пока не дойдёшь до середины. Главное — не забыть найти конец строки, а то так и будешь менять местами символы до скончания веков, пока не наткнёшься на случайный нуль-терминатор в памяти. Будет тебе хиросима и нигерсраки в одном флаконе.
#include <cstring>
void reverse_c_string(char* str) {
if (!str) return;
char* end = str + strlen(str) - 1;
while (str < end) {
std::swap(*str, *end); // или ручной обмен через временную переменную
++str;
--end;
}
}
Вот и весь сказ. Не усложняй, используй готовое. И да, чувак, доверия ебать ноль к тем, кто это вручную в десять строк пишет.