Имея такое многообразие алгоритмов поиска, у вас должна быть возможность найти то, что вы ищете, а если такой возможности нет, используйте свои собственные алгоритмы. Однако если basic_string не предоставляет то, что требуется, то перед написанием своего кода посмотрите на . Стандартные алгоритмы работают с последовательностями, используя итераторы и почти также часто — объекты функций. Для удобства и простоты переноса basic_string предоставляет итераторы, так что подключение итераторов string к стандартным алгоритмам является тривиальным. Скажем, вам требуется найти первое вхождение двух одинаковых символов подряд. Для поиска двух одинаковых расположенных рядом («расположенных рядом» означает, что их позиции отличаются на один шаг итератора, т.е. *iter == *(iter + 1)) символов в строке используйте шаблон функции adjacent_find.
std::string s = "There was a group named Kiss in the 70s";
std::string::iterator p =
std::adjacent_find(s.begin(), s.end());
Результатом будет итератор, указывающий на первый из двух смежных элементов.
Если вам требуется написать собственный алгоритм работы со строками, не используйте basic_string так, как это делается со строками в стиле С, используя для доступа к элементам operator[]. Используйте существующие методы. Каждая функция поиска принимает параметр size_type, указывающий индекс, с которого должен начаться поиск. Последовательно используя функции поиска, можно пройти по всей строке. Рассмотрим пример 4.16, который подсчитывает число уникальных символов в строке.
#include
#include
template
int countUnique(const std::basic_string
using std::basic_string;
basic_string
for (typename basic_string
p != s.end(); ++p) {
if (chars.find(*p) == basic.string
chars += *p;
}
return(chars.length());
}
int main() {
std: :string s = "Abracadabra'";
std::cout << countUnique(s) << '\n';
}
Функции поиска очень часто оказываются полезными. Когда требуется найти что- либо в строке типа string, они должны быть первым, что следует использовать.
4.10. Поиск n-го вхождения подстроки
Имея источник source и шаблон pattern типа string, требуется найти n-е вхождение pattern в source.
Для поиска последовательных вхождений искомой подстроки используйте метод find. Пример 4.17 содержит простую функцию nthSubstr.
#include
#include
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.
#include
#include
using namespace std;
template
int nthSubstrg(int n, const basic_string
const basic_string
string::size_type i = s.find(p);