int main() {
std: :string s = 'Abracadabra'';
std::cout << countUnique(s) << '
';
}
Функции поиска очень часто оказываются полезными. Когда требуется найти что- либо в строке типа string
, они должны быть первым, что следует использовать.
4.10. Поиск n-го вхождения подстроки
Имея источник source
и шаблон pattern
типа string
, требуется найти n
-е вхождение pattern
в source
.
Для поиска последовательных вхождений искомой подстроки используйте метод find
. Пример 4.17 содержит простую функцию nthSubstr
.
#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) << '
';
cout << nthSubstr(2, s, p) << '
';
cout << nthSubstr(5, s, p) << '
';
}
В функцию nthSubstr
, имеющую вид, показанный в примере 4.17, можно внести пару улучшений. Во-первых, ее можно сделать общей, сделав из нее вместо обычной функции шаблон функции. Во-вторых, можно добавить параметр, позволяющий учитывать подстроки, которые перекрываются друг с другом. Под перекрывающимися подстроками я понимаю такие, у которых начало строки соответствует части конца такой же строки, как в строке «abracadabra», где последние четыре символа такие же, как и первые четыре. Это демонстрируется в примере 4.18.
#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) << '
';
cout << p << ' с повторениями встречается в позиции '
<< nthSubstrg(3, s, p, true) << '
';
}
Вывод для строк, использованных в примере 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
находит первое вхождение подстроки.
На практике встречается огромное количество вариаций на тему поиска и удаления подстрок.