С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
zzzZZZ...
 Аватар для dzrkot
527 / 358 / 94
Регистрация: 11.09.2013
Сообщений: 2,041

STL и string

04.06.2014, 12:53. Показов 1899. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
начал тут 1 задачу на форуме решать
в text1 какой-то текст, мы ищем в нем слова str и после них вставляем слова str2

вообщем я не могу придумать решение при помощи STL, по идее применяю search. записываю результат в итератор
, затем insert в позицию этого итератора, если it1==txt.end() то выходим ....вообещм подскажите не умею решать такого плана задачи пока что =(
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>
#include <algorithm>
 
using namespace std;
 
int main()
{
ifstream in("text1.txt");
string str,txt,str2;
while(!in.eof())
  {
  getline(in,str);
  txt+=str+'\n';
  }
cout<<"enter search word : "<<endl;
cin>>str;
cout<<"enter cin word : "<<endl;
cin>>str2;
str2=" "+str2+" ";
string::iterator it1=txt.begin();
int i=0;
 
while(it1!=txt.end())
  {
  cout<<*(it1=search(it1,txt.end(),str.begin(),str.end()));
     if(it1!=txt.end())
  txt.insert(it1,str2.begin(),str2.end());
  }
cout<<endl<<txt;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.06.2014, 12:53
Ответы с готовыми решениями:

Размышления о string из STL
Класс string из шаблона STL замечательная вещь! Но вчера он меня чуть не убил... #include &lt;string&gt; using namespace std ... ...

[STL] Работа со std::string
Привет, форум. Подскажите, как можно грамотно скопировать &quot;слово&quot; из строки, с указанием начала и конца позиций. Например: string...

Undefined symbol string (STL)
подключаю следующие библиотеки #include &lt;iostream.h&gt; #include &lt;vector.h&gt; #include &lt;string.h&gt; using namespace std; void...

13
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2223 / 1425 / 420
Регистрация: 16.05.2013
Сообщений: 3,642
Записей в блоге: 6
04.06.2014, 13:44
Тонкость в том, что в классе string (впрочем как и в vector) нет подходящей ф-и insert. Проблема возникает из-за того, что вставка может привести к перераспределению памяти для контейнера и как следствие все итераторы станут валидными. Думаю здесь лучше выполнять вставку копированием. Т.е. вводим вспомогательную строку в которую будем записывать исходную строку кусками. В тех местах где будет вхождение искомой подстроки мы добавляем к временной другую подстроку и продолжаем поиск подстроки дальше.
Примерная реализация(не проверял) :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  std::string text;
  std::string output;
  std::string w1, w2;
 
  std::cout << "Input w1: ";
  std::cin >> w1;
  std::cout << "Input w2: ";
  std::cin >> w2;
 
  //Заносим исходный текст в text
/*
...
*/
  
  std::string::iterator iterlo = text.begin();
  std::string::iterator iterhi = text.begin();
 
  do {
    iterhi = std::search(iterlo, text.end(), w1.begin(), w1.end());
    std::copy(iterlo, iterhi, std::back_inserter(output));
    if (iterhi != text.end())
      output += w1 + ' ' + w2;
    iterlo = iterhi + w1.size();
    iterhi = iterlo;
  } while(iterhi != text.end());
1
zzzZZZ...
 Аватар для dzrkot
527 / 358 / 94
Регистрация: 11.09.2013
Сообщений: 2,041
04.06.2014, 13:49  [ТС]
Цитата Сообщение от Ilot Посмотреть сообщение
Тонкость в том, что в классе string (впрочем как и в vector) нет подходящей ф-и insert. Проблема возникает из-за того, что вставка может привести к перераспределению памяти для контейнера и как следствие все итераторы станут валидными. Думаю сдесьлучше выполнять вставку копирование. Т.е. вводим вспомогательную строку в которую будем записывать исходную строку кусками. В тех местах где будет вхождение искомой подстроки мы добавляем к временной другую подстроку и продолжаем поиск подстроки дальше.
спасибо, такой вариант мне показался менее эстетичным, я думал что можно решить это именно вставкой, мб как-то через insert_iterator (но для string вроде его нет). Как вариант ещё перегнать из string в другой контейнер, и там делать вставку, но проще уж тогда действительно использовать доп string и конкатенацию
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2223 / 1425 / 420
Регистрация: 16.05.2013
Сообщений: 3,642
Записей в блоге: 6
04.06.2014, 14:12
insert_iterator это врапер для метода insert. Что в лоб, что по лбу. Можно конечно использовать посимвольную вставку
C++
1
iterator insert (iterator position, const value_type& val);
Но я думаю вы понимаете, к чему приведет эта идея...
Однако не все так плохо. У нас ведь есть списки. Посимвольная вставка для них имеет такую же сигнатуру, что и для других контейнеров, но выполняется за константное время. Эти соображения наводят нас на мысль, что все же лучше использовать не контейнер string, а list.
3
04.06.2014, 15:24

Не по теме:

Цитата Сообщение от Ilot Посмотреть сообщение
и как следствие все итераторы станут валидными
Перестанут быть, наверное имелось в виду.

0
04.06.2014, 17:09

Не по теме:

Цитата Сообщение от Ilot Посмотреть сообщение
все итераторы станут валидными
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Перестанут быть, наверное имелось в виду.
да бывает. Главное же понятно, что
все не итераторы станут валидными
вернее
не все итераторы станут валидными
то есть старые лучше не использовать, после каждой операции. :)

0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
04.06.2014, 18:48
Лучший ответ Сообщение было отмечено dzrkot как решение

Решение

Либо я чего-то не понял, либо одно из двух...

Цитата Сообщение от Ilot Посмотреть сообщение
Тонкость в том, что в классе string (впрочем как и в vector) нет подходящей ф-и insert.
Как нет?
http://www.cplusplus.com/refer... ng/insert/

Цитата Сообщение от Ilot Посмотреть сообщение
Думаю здесь лучше выполнять вставку копированием
Омг, зачем? Идти по строке и на ее основе строить новую где-то в третьем месте... Сложно. И получаются двойные затраты по памяти. Как отметил выше, есть insert, который решает задачу. Инвалидация итераторов? И черт с ними - не будем вообще их использоавть.

Цитата Сообщение от Ilot Посмотреть сообщение
У нас ведь есть списки. Посимвольная вставка для них имеет такую же сигнатуру, что и для других контейнеров, но выполняется за константное время.
Только аллокаций памяти на каждый символ нам не хватало.

От слов к коду:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
 
int main() {
    std::string origin = "list string vector list map map list vector string list";
    const std::string search_str = "list";
    const std::string additional_str = "&&";
    
    size_t pos = 0;
    
    while ((pos = origin.find(search_str, pos)) != std::string::npos) {
        pos += search_str.size();
        origin.insert(pos, additional_str);
        pos += additional_str.size();
    }
    
    std::cout << origin << std::endl;
    
    return 0;
}
http://ideone.com/Atkrz3
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.06.2014, 18:55
Лучший ответ Сообщение было отмечено Psilon как решение

Решение

dzrkot, а что если регулярками? Они как раз для таких случаев и нужны. За один проход чтобы осуществить все замены.

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <regex>
 
using namespace std;
 
int main() {
    const string origin = "list string vector list map map list vector string list";
    const string search_str = "list";
    const string additional_str = "&&";
    regex e(search_str);
    string result = regex_replace(origin, e, "$0" + additional_str);
    cout << result << endl;
    return 0;
}
1
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
04.06.2014, 18:57
Psilon, из пушки по воробьям. Такое же двойное использование памяти + регулярки же. Краткость записи, конечно, соблазнительна, но они явно для задач более сложных.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6101 / 4957 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.06.2014, 19:03
0x10, двойное использование памяти - возможно, но вот скорость должна быть выше. Насколько я помню, там идет всего лишь один проход по строке КМП-алгоритмом с построением суффиксного дерева. А в случае с find будет N+1 проходов по строке. При этом при insert афайк приходится все равно докидывать конец массива дальше, чтобы вставляемая строка влезла. Ну и краткость, конечно, куда без неё

Добавлено через 2 минуты
Краткость записи, конечно, соблазнительна, но они явно для задач более сложных.
ятп они подходят для большинства типичных работ со строками. В первую очередь тех, которые подразумевают несколько проходов по строке, когда можно обойтись одним. Сколько бы приколов и анекдотов ни ходило про регулярки, они в своей области очень хороший инструмент (если не заходит речь про валидацию email-адресов, конечно )
0
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
04.06.2014, 19:27
Цитата Сообщение от Psilon Посмотреть сообщение
А в случае с find будет N+1 проходов по строке.
У меня ровно один проход - в find передается позиция, с которой начинать поиск.

Добавлено через 21 минуту
Пононял тесты - ок, верю - с регулярками получается быстрее.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
05.06.2014, 03:39
Цитата Сообщение от 0x10 Посмотреть сообщение
Как нет?
0x10, не уверен, но думаю Ilot, не имел ввиду, что её нет. Вставка в последовательный контейнер (особенно где-то в начало) это тоже перевыделение, пусть и не посимвольное. У ассоциативного контейнера поэлементное выделение, но один раз.
Мощность холивара пропорциональна количеству вставок в одну и ту же строку.
Psilon, вчера я чуток помучился с replace С#. Причем если бы меня спросили, то ответил бы, что ф-ция член возвращает новую копию строки. Но никто (и я сам себя) не спросил... Пару часов ломился. Вызываю, а строка как дуська не меняется! Потом посмотрел в документацию и в первых же словах нашёл.
Родство ситуации в том, что в многобайтовой кодировке replace-фрагмент может не соответствовать замещаемому по размеру и получается та же дилемма, что и при вставке. Авторы почли за лучшее сделать то, о чём Ilot говорит. Или я не понял как всегда.
1
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
05.06.2014, 08:30
boost::replace
0
Эксперт по математике/физикеЭксперт С++
 Аватар для Ilot
2223 / 1425 / 420
Регистрация: 16.05.2013
Сообщений: 3,642
Записей в блоге: 6
05.06.2014, 08:42
Цитата Сообщение от 0x10 Посмотреть сообщение
Как нет?
Ключевое слово:
Цитата Сообщение от Ilot Посмотреть сообщение
Тонкость в том, что в классе string (впрочем как и в vector) нет подходящей ф-и insert.
Т.е. нет функции вставляющей строку и возвращающей итератор за последним символом вставленной строки. Есть только функция член вставляющая символ.
Цитата Сообщение от 0x10 Посмотреть сообщение
Омг, зачем? Идти по строке и на ее основе строить новую где-то в третьем месте... Сложно. И получаются двойные затраты по памяти.
Верно двойные затраты по памяти. Зато нет квадратичных затрат при смещении символов во время вставки.
Цитата Сообщение от 0x10 Посмотреть сообщение
Только аллокаций памяти на каждый символ нам не хватало.
Согласен. Это может быть тоже плохим решением. Чрезмерное использование памяти.
Спасибка за то что никогда не умел работать с size_type и npos.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.06.2014, 08:42
Помогаю со студенческими работами здесь

STL sort строк string по убыванию
Как по возрастанию - знаю:std::vector&lt;std::string&gt; obj; std::string str(&quot;asdfghjkl&quot;); vector.push_back(str); for (auto &amp;index :...

Использование контейнера string из библиотеки STL
Дан массив слов. Сформировать новое слово из символов слов массива, стоящих после последнего символа ‘*’ в слове. Сформировать предложение...

Еще одно размышление о string из STL
Если строки в STL по стандарту могут совместно использовать дин и тот же участок памяти (а это именно следуя из стандарта), тогда следующие...

STL String. Вывести слово и после него количество символов
Здраствуйте! У меня есть например строка string, покажите пожалуйста на примере как можно выделять слова этой строки, например вывести...

System::String^ vs stl::std::string
В консольном варианте есть программа, которая получает с экрана строку типа string, работает с ней и выдает результат. Необходимо все...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru