Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

4.10. Поиск n-го вхождения подстроки

Проблема

Имея источник

source
и шаблон
pattern
типа
string
, требуется найти
n
– е вхождение
pattern
в
source
.

Решение

Для поиска последовательных вхождений искомой подстроки используйте метод

find
. Пример 4.17 содержит простую функцию
nthSubstr
.

Пример 4.17.

Поиск n-го вхождения подстроки

#include <string>

#include <iostream>

using namespace std;

int nthSubstr(int n, const strings s,

 const strings p) {

 string::size_type i = s.find(p); // Найти первое вхождение

 int j;

 for (j = 1; j < n && i != string::npos; ++j)

i = s.find(p, i+1); // Найти следующее вхождение

 if (j == n) return(i);

 else return(-1);

}

int main (

 string s = "the wind, the sea, the sky, the trees";

 string p = "the";

 cout << nthSubstr(1, s, p) << '\n';

 cout << nthSubstr(2, s, p) << '\n';

 cout << nthSubstr(5, s, p) << '\n';

}

Обсуждение

В функцию

nthSubstr
, имеющую вид, показанный в примере 4.17, можно внести пару улучшений. Во-первых, ее можно сделать общей, сделав из нее вместо обычной функции шаблон функции. Во-вторых, можно добавить параметр, позволяющий учитывать подстроки, которые перекрываются друг с другом. Под перекрывающимися подстроками я понимаю такие, у которых начало строки соответствует части конца такой же строки, как в строке «abracadabra», где последние четыре символа такие же, как и первые четыре. Это демонстрируется в примере 4.18.

Пример 4.18. Улучшенная версия nthSubstr

#include <string>

#include <iostream>

using namespace std;

template<typename T>

int nthSubstrg(int n, const basic_string<T>& s,

 const basic_string<T>& p, bool repeats = false) {

 string::size_type i = s.find(p);

 string::size_type adv = (repeats) ? 1 : p.length;

 int j;

 for (j = 1; j < n && i != basic_string<T>::npos; ++j)

i = s.find(p, i+adv);

 if (j == n)

return(i);

 else

return(-1);

}

int main {

 string s = AGATGCCATATATATACGATATCCTTA";

 string p = "ATAT";

 cout << p << "
без повторений встречается в позиции "

<< nthSubstrg(3, s, p) << '\n';

 cout << p << " с повторениями встречается в позиции "

<< nthSubstrg(3, s, p, true) << '\n';

}

Вывод для строк, использованных в примере 4.18, выглядит так.

ATAT без повторений встречается в позиции 18

ATAT с повторениями встречается в позиции 11

Смотри также

Рецепт 4.9.

4.11. Удаление подстроки из строки

Проблема

Требуется удалить из строки подстроку.

Решение

Используйте методы

basic_string find
,
erase
и
length
:

std::string t = "Banana Republic";

std::string s = "nana";

std::string::size_type i = t.find(s);

if (i != std::string::npos) t.erase(i, s.length);

Этот код удаляет

s.length
элементов, начиная с индекса, по которому
find
находит первое вхождение подстроки.

Обсуждение

На практике встречается огромное количество вариаций на тему поиска и удаления подстрок. Например, может потребоваться удалить все вхождения подстроки, а не одно из них. Или только последнее. Или седьмое. Каждый раз действия будут одни и те же: найдите индекс начала шаблона, который требуется удалить, затем вызовите

erase
для этого индекса и n последующих символов, где n — это длина строки шаблона. За описанием различных методов поиска подстрок обратитесь к рецепту 4.9.

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

Пример 4.19. Удаление всех подстрок из строки (обобщенная версия)

#include <string>

#include <iostream>

using namespace std;

template<typename T>

Поделиться:
Популярные книги

Жалкая

Макинтайер Эмили
3. Долго и Несчастливо
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Жалкая

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Академия проклятий. Книги 1 - 7

Звездная Елена
Академия Проклятий
Фантастика:
фэнтези
8.98
рейтинг книги
Академия проклятий. Книги 1 - 7

Измена. Верни мне мою жизнь

Томченко Анна
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верни мне мою жизнь

Измена

Рей Полина
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Измена

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сердце для стража

Каменистый Артем
5. Девятый
Фантастика:
фэнтези
боевая фантастика
9.20
рейтинг книги
Сердце для стража

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Жена фаворита королевы. Посмешище двора

Семина Дия
Фантастика:
фэнтези
5.00
рейтинг книги
Жена фаворита королевы. Посмешище двора

Как я строил магическую империю 5

Зубов Константин
5. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 5

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Маленькая слабость Дракона Андреевича

Рам Янка
1. Танцы на углях
Любовные романы:
современные любовные романы
эро литература
5.25
рейтинг книги
Маленькая слабость Дракона Андреевича