Как добавить символ в строку
Перейти к содержимому

Как добавить символ в строку

  • автор:

Добавить символ в строку в заданной позиции

Мы представим три реализации простой функции, которая принимает исходную строку, символ и позицию, в которую нам нужно ее добавить.

Поскольку класс 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 . Он подготавливает строку путем объединения:

  1. Подстрока исходной строки перед позицией
  2. Новый персонаж
  3. Подстрока исходной строки после позиции
 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. Вывод

Как добавить символ в строку

Если надо добавить в конец строки другую строку, применяется метод 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.

вставка символа в строку

Задача простая - есть строка, например std::string("sfsfsgsdshhdfjj"), необходимо вставить через каждый второй символ символ "-".Не пойму как такое реализовать, пожалуйста подскажите.

Отслеживать
задан 28 апр 2016 в 5:19
1,969 3 3 золотых знака 18 18 серебряных знаков 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
222k 15 15 золотых знаков 120 120 серебряных знаков 234 234 бронзовых знака
я бы добавил: 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); 

Как вставить символ в строку python?

Как вставить символ по определенному индексу в строку?

  • Вопрос задан более трёх лет назад
  • 27149 просмотров

Комментировать
Решения вопроса 2

hottabxp

Сергей Карбивничий @hottabxp Куратор тега Python
Сначала мы жили бедно, а потом нас обокрали..
Можно использовать срезы:

a = 'bigben' print(a[:3],'.',a[3:],sep='') >>> big.ben

или так: print(f'.')
Ответ написан более трёх лет назад
Нравится 2 1 комментарий
Сергей Ильин @sunsexsurf

вообще, задание похоже на энтерпрайзный хеллоу-ворлд. Типа, ну ок, ф-строки - норм, теперь давайте регулярками разобъем. Или как-то еще мэтчить будем ))

Makaroshka007

Тимур Покровский @Makaroshka007
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Ответы на вопрос 1

*новое слово*=слово[:позиция-1]+'.'+слово[позиция:]
word = 'bigben'
position = 3
new_word = word[:position - 1] + '.' + word[position:]

Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

python

  • Python
  • +2 ещё

'latin-1' codec can't encode characters in position 36-40: ordinal not in range(256)?

  • 1 подписчик
  • 5 минут назад
  • 7 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *