вставка символа в строку
Задача простая — есть строка, например std::string(«sfsfsgsdshhdfjj»), необходимо вставить через каждый второй символ символ «-«.Не пойму как такое реализовать, пожалуйста подскажите.
Отслеживать
задан 28 апр 2016 в 5:19
1,993 3 3 золотых знака 16 16 серебряных знаков 34 34 бронзовых знака
Не правьте, пожалуйста, вопросы, изменяя метки, меняя точки на запятые и добавляя кавычки/ненужные метки, зарабатывая по +2 репутации. Вносите бОльшие изменения в вопрос, чтобы он был полезней, либо не меняйте его. Это не приносит пользы вопросам и сообществу в целом. Спасибо.
15 сен 2016 в 14:52
@Denis — пожалуйста! Исправлять орфографические ошибки и правила расстановки знаков препинания не нужно? Нет? Делать вопросы более понятными для всех не нужно. Я все исправляю по правилам форума. Я не просто зарабатываю 2 балла репутации — но и делаю полезное дело! И да — это приносит пользу сообществу!
15 сен 2016 в 16:14
Например, вот эта правка не несёт пользы вопросу — кавычки тут не нужны, как и точка после ссылки, есть даже причина для отклонения таких правок — «Правка никак не делает сообщения более простым к прочтению, не упрощает его поиск, точность или доступность. Изменения абсолютно излишни или явно ухудшают читаемость.»
16 сен 2016 в 6:55
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
Самый простой способ, пожалуй, — создать новую строку и посимвольно туда запихивать все это хозяйство.
string s("sfsfsgsdshhdfjj"); string d; for(auto c: s)
Update Как оказалось, не совсем верно понял, дефис надо через два на третий. Примерно так:
string d; for(size_t i = 0; i < s.length(); ++i) < d += s[i++]; if (i < s.length()) < d += s[i]; d += '-'; >>
Отслеживать
ответ дан 28 апр 2016 в 5:39
218k 15 15 золотых знаков 117 117 серебряных знаков 229 229 бронзовых знаков
я бы добавил: d.reserve(s.length()*2-1)
28 апр 2016 в 5:58
Да, согласен, несколько быстрее. Тут — ideone.com/Jmlwde — сравнение с резервированием, без и с методом вставкой.
28 апр 2016 в 6:17
А вообще, самый быстрый вот такой: ideone.com/B4C7xG объясняю почему: operator[] не выполняет никаких проверок вообще, а operator+= — выполняет. Как минимум — вдруг ёмкость исчерпалась, а значит нужно как бы и памяти добавить. Правило наименьшего оверхеда вкупе с наименьшим удивлением. Ваш вариант ещё и ошибку содержит: всегда добавляется — во конце, хотя не должен вообще. Пруф: ideone.com/VbE5RW
28 апр 2016 в 8:02
Решение @Harry быстрое, а если жалко памяти на два буффера сразу, то можно либо как у вас или так (дополнительной памяти O(1)):
// Резервируем память, что бы исключить реаллокации при вставке s.reserve(s.length()*3/2); for (size_t i = 2; i < s.length(); i+=2) s.insert(i++, 1, '-'); // инкремент тут нужен, что бы уйти с только что вставленного '-'
Минус: оно медленное за счёт того, что при каждой вставке нужно делать memmove / memcpy для оставшихся символов.
UPD: поправлено под условие (каждый второй символ)
UPD2: самый (пока?) шустрый вариант (дополнительной памяти O(n)):
string str; str.resize(s.length() * 3/2); size_t size = 0; for (size_t i = 0; i < s.length(); ++i) < str[size++] = s[i++]; if (i < s.length()) < str[size++] = s[i]; if (i != s.length() - 1) str[size++] = '-'; >> // ;-) str.resize(size);
Как добавить символ в строку
Если надо добавить в конец строки другую строку, применяется метод append() , в который передается добавляемая строка:
#include #include int main() < std::string message< "hello">; message.append(" "); // добавляем пробел message.append("world"); // можно добавить по цепочке // message.append(" ").append("world"); std::cout
Вставка строки
Для вставки одной строки в другую применяется функция insert() . Она имеет несколько различных версий. Самая простая версия принимет индекс вставки и вставляемую строку:
#include #include int main() < std::string text ; std::string str ; text.insert(7, str); std::cout
В данном случае в строку text начиная с 7-го индекса вставляем строку str. В итоге переменная text будет равна "insert a string into a text".
Также можно вставлять строковый литерал:
std::string text ; text.insert(6, "C/"); // Hello C/C++
Можно вставлять часть подстроки:
std::string text ; std::string langs ; text.insert(6, langs, 5, 3); // Langs: C, C++
Здесь в text вставляем из переменной langs 3 символа с 5-го индекса, то есть подстроку " C,".
Среди других версий функции insert() также следует отметить версию, которая позволяет вставить определенный символ определенное число раз:
std::string text ; text.insert(8, 5, '*'); // Number: *****5678
В данном случае вставляем в строку text символ * 5 раз начиная с 8 индекса.
Замена подстроки
Для замены в строке некоторой части применяется функция replace() . Эта функция также имеет много версий, поэтому рассмотрим самые распространенные.
Самая простая версия принимает три параметра:
std::string &std::string::replace(size_t _Off, size_t _Nx, const char *_Ptr)
Первый параметр - представляет индекс, с которого надо заменять подстроку. Второй параметр - количество заменяемых символов. Третий параметр - на какую строку надо заменить. Пример:
#include #include int main() < std::string text ; text.replace(6, 4, "C++"); // Lang: C++ std::cout
Здесь в строке text заменяем 4 символа с 6-го индекса на строку "C++". Таким образом, из строки "Lang: Java" мы получим строку "Lang: C++".
В предыдущем примере символы заменялись на строковый литерал. Но также можно заменять на объект string:
std::string text ; std::string lang <"C++">; text.replace(6, 4, lang); // Lang: C++
Нередко стоит задача заменить какой-то определенную подстроку, индекс которой может быть не известен. В этом случае мы можем воспользоваться поиском в строке, чтобы найти индекс подстроки и ее размер. Например, возьмем текст "Hello, Tom!" и заменим подстроку "Tom" на "Bob":
#include #include int main() < std::string text ; const std::string separators ; // разделители слова size_t start ; // находим позицию подстроки size_t end; // Находим конец подстроки if(end == std::string::npos) // если разделители слова не найдены < end = text.length(); >text.replace(start, end - start, "Alice"); // заменяем подстроку std::cout
Здесь находим позицию первого символа подстроки "Tom" в тексте и сохраняем ее в переменную start. Символ, следующий за последним символом подстроки "Tom", находится путем поиска символа разделителя из строки separators с помощью функции find_first_of() . Далее используем найденные позиции индекса в replace() .
Однако в тексте может быть множество вхождений определенной подстроки (в нашем случае строки "Tom"), и может встать задача заменить все эти вхождения. Для этого мы можем использовать циклы:
#include #include int main() < std::string text ; std::string old_str; // какую подстроку заменить std::string new_str; // на какую строку заменить size_t start ; // находим позицию подстроки while (start != std::string::npos) // находим и заменяем все вхождения строки old_str < text.replace(start, old_str.length(), new_str); // Замена old_str на new_str start = text.find(old_str, start + new_str.length()); >std::cout
Здесь сначала находим индекс первого вхождения подстроки, которую надо заменить, и сохраняем этот индекс в переменную start. В цикле заменяем последовательно все вхождения подстроки. После каждой замены находим индекс следующего вхождения, сохраняем его в переменную start и повторяем цикл. Когда больше нет вхождений подстроки в текст, start будет содержать значение std::string::npos , что завершает цикл.
Из других версий функции replace() можно выделить функцию, которая заменяет подстроку определенным символом, который повторяется определенное количество раз:
std::string text ; text.replace(9, 6, 5, '*'); // Phone: +1*****8901
Здесь заменяет в строке text 6 символов начиная с 9-го индекса на 5 символов *.
Удаление символов
Если надо не просто заменить символы, а удалить их из текста, также можно использовать функцию replace() - в этом случае удаляемые символы фактически заменяются на пустую строку:
#include #include int main() < std::string text ; const std::string empty; text.replace(5, 4, empty); // Замена "Tom" на пустую строку std::cout
Однако С++ также предоставляет для удаления символов специальную функцию - erase() . В качестве параметров она принимает начальный индекс удаления и количество удаляемых символов:
#include #include int main() < std::string text ; text.erase(5, 4); // удаляем 4 символа с 5-го индекса std::cout
Аналогично можно удалить все вхождения определенной подстроки:
#include #include int main() < std::string text ; std::string to_delete; // какую подстроку удалить size_t start ; // находим позицию подстроки while (start != std::string::npos) // находим и удаляем все вхождения to_delete < text.erase(start, to_delete.length()); start = text.find(to_delete, start + to_delete.length()); >std::cout
Функция erase() имеет ряд дополнительных версий. Так, можно оставить определенное количество символов с начала строки, а остальные удалить:
std::string text ; text.erase(5); // удаляем все кроме первых 5 символов - остается "Hello"
Если в функцию не передается никаких параметров, то она удаляет все символы, и в результате получаем пустую строку:
std::string text ; text.erase(); // пустая строка
Стоит отметить, что в стандарт С++20 была добавлена функция std::erase() , которая удаляет все вхождения определенного символа в строке:
#include #include int main() < std::string text ; std::erase(text, 'T'); // Удаляем символ T std::cout
В данном случае удаляем из строки text символ T.
Добавить символ в конец строки в C++
В этой быстрой статье мы рассмотрим различные методы добавления символа в конец строки в C++.
1. Использование push_back() функция
Рекомендуемый подход заключается в использовании стандартного push_back() функция, которая перегружена для символов и добавляет символ в конец строки.
std :: string s = "C+" ;
s . push_back ( ch ) ;
std :: cout << s ;
2. Использование += оператор
Мы также можем использовать string::operator+= , который перегружен для символов и внутренних вызовов push_back() функция.
std :: string s = "C+" ;
std :: cout << s ;
3. Использование append() функция
Другим приемлемым подходом является использование append() функция для добавления одной копии символа в конец строки, как показано ниже:
std :: string s = "C+" ;
s . append ( 1 , ch ) ;
std :: cout << s ;
4. Использование std::stringstream функция
Другой хорошей альтернативой является использование строкового потока для преобразования между строками и другими числовыми типами.
std :: string s = "C+" ;
std :: stringstream ss ;
std :: cout << s ;
5. Использование insert() функция
Наконец, мы также можем использовать insert() Функция для вставки одной копии символа в указанную позицию в строке.
std :: string s = "C+" ;
s . insert ( s . length ( ) , 1 , ch ) ;
std :: cout << s ;
Это все о добавлении символа в конец строки в C++.
Оценить этот пост
Средний рейтинг 4.56 /5. Подсчет голосов: 91
Голосов пока нет! Будьте первым, кто оценит этот пост.
Сожалеем, что этот пост не оказался для вас полезным!
Расскажите, как мы можем улучшить этот пост?
Спасибо за чтение.
Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.
Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования :)
Подписывайся
6 Комментарии
Большинство голосов
Новейшие Самый старый
Встроенные отзывы
Просмотреть все комментарии
Просмотр комментариев
Загрузить больше комментариев
Просматривать
Подпишитесь на новые публикации
- Все проблемы
- Практика DSA
- 100 самых популярных задач
- 50 лучших классических задач
- Лучшие алгоритмы
- Компилятор С/С++
- Компилятор Java
- Компилятор Python
- Компилятор JavaScript
- компилятор PHP
- Компилятор C#
- Свяжитесь с нами
- Политика конфиденциальности
- условия обслуживания
- Подпишитесь на новые публикации
Techie Delight © 2023 Все права защищены.
Этот веб-сайт использует файлы cookie. Используя этот сайт, вы соглашаетесь с использованием файлов cookie, нашей политикой, условиями авторского права и другими условиями. Читайте наши Политика конфиденциальности. Понятно
Добавить символ в строку в заданной позиции
Мы представим три реализации простой функции, которая принимает исходную строку, символ и позицию, в которую нам нужно ее добавить.
Поскольку класс String является окончательным и неизменяемым , функция должна возвращать новую строку с добавленным символом.
2. Использование массива символов
Здесь идея состоит в том, чтобы создать новый массив символов и скопировать символы из исходной строки перед заданной позицией.
После этого мы помещаем новый символ в позицию и копируем остальные символы из исходной строки в последующие позиции нового массива.
Наконец, мы создаем нужную строку из этого массива.
public String addChar(String str, char ch, int position) int len = str.length(); char[] updatedArr = new char[len + 1]; str.getChars(0, position, updatedArr, 0); updatedArr[position] = ch; str.getChars(position, len, updatedArr, position + 1); return new String(updatedArr); >
По сравнению с двумя другими методами, это низкоуровневый подход к проектированию, обеспечивающий наибольшую гибкость.
3. Использование метода подстроки
Более простой и высокоуровневый подход — использовать метод substring() класса String . Он подготавливает строку путем объединения:
- Подстрока исходной строки перед позицией
- Новый персонаж
- Подстрока исходной строки после позиции
public String addChar(String str, char ch, int position) return str.substring(0, position) + ch + str.substring(position); >
Хотя приведенный выше код более удобочитаем, у него есть недостаток, заключающийся в том, что он создает ряд временных объектов для определения результата. Поскольку String является неизменяемым классом, каждый вызов его метода substring() создает новый экземпляр String .
Наконец, когда мы объединяем части, компилятор создает объект StringBuilder для добавления их по одной. Каждый объект String и StringBuilder выделяет отдельные области памяти для своего внутреннего массива символов.
Эта реализация также должна трижды копировать все символы из одного массива в другой.
Если нам нужно вызвать метод огромное количество раз, временные объекты могут заполнить динамическую память, и это будет очень часто запускать сборщик мусора. Это также может в некоторой степени повлиять на производительность.
4. Использование StringBuilder
StringBuilder — это служебный класс, предоставляемый библиотекой Java для создания объектов String и управления ими различными способами.
Мы можем реализовать ту же функциональность, используя метод insert() класса StringBuilder :
public String addChar(String str, char ch, int position) StringBuilder sb = new StringBuilder(str); sb.insert(position, ch); return sb.toString(); >
Приведенный выше код должен создать только один объект StringBuilder , чтобы вставить символ в позицию. Он выделяет тот же объем памяти, что и исходная строка , но для создания места для нового символа базовый массив сдвигает следующие символы на 1 позицию.
Хотя использование StringBuilder может быть медленнее, оно не требует памяти для инициализации временных объектов. Мы также получаем простой и читаемый код.
5. Вывод
В этой статье мы сосредоточились на нескольких способах добавления символа в объект String в Java . Мы видели, что реализация с использованием массива символов обеспечивает наилучшую производительность, а реализация с использованием метода подстроки обеспечивает более читаемый подход.
Предпочтительным способом реализации решения является использование класса StringBuilder , так как он прост, менее подвержен ошибкам и обеспечивает хорошую и стабильную производительность .
Как обычно, полный исходный код приведенного выше руководства доступен на GitHub .
- 1. Введение
- 2. Использование массива символов
- 3. Использование метода подстроки
- 4. Использование StringBuilder
- 5. Вывод