Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
std: :string s = "Abracadabra'";
std::cout << countUnique(s) << '\n';
}
Функции поиска очень часто оказываются полезными. Когда требуется найти что- либо в строке типа string
, они должны быть первым, что следует использовать.
4.10. Поиск n-го вхождения подстроки
Имея источник source
и шаблон pattern
типа string
, требуется найти n
-е вхождение pattern
в source
.
Для поиска последовательных вхождений искомой подстроки используйте метод find
. Пример 4.17 содержит простую функцию nthSubstr
.
Пример 4.17. Поиск n-го вхождения подстроки
#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.
Пример 4.18. Улучшенная версия nthSubstr
#include
#include
using namespace std;
template
int nthSubstrg(int n, const basic_string& s,
const basic_string& 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::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
#include
using namespace std;
template
void removeSubstrs(basic_string& s,
const basic_string& p) {
basic_string::size_type n = p.length();
for (basic_string::size_type i = s.find(p);
i != basic_string::npos; i = s.find(p))
s.erase(i, n);
}
int main() {
string s = "One fish, two fish, red fish, blue fish";
string p = "fish";
removeSubstrs(s, p);
cout << s << '\n';
}
Здесь всю важную работу выполняет метод erase basic_string
. В он перегружен три раза. Использованная в примере 4.19 версия принимает индекс, с которого требуется начать удаление, и число удаляемых символов. Другая версия принимает в качестве аргументов начальный и конечный итераторы, а также есть версия, которая принимает единственный итератор и удаляет элемент, на который он указывает. Чтобы обеспечить оптимальную производительность при планировании удаления нескольких последовательных элементов, используйте первые две версии и не вызывайте s.erase(iter)
несколько раз для удаления каждого из идущих подряд элементов. Другими словами, используйте методы, работающие с диапазонами, а не с одним элементом, особенно в случае тех методов, которые изменяют содержимое строки (или последовательности). В этом случае вы избежите дополнительных вызовов функции erase
для каждого элемента последовательности и позволите реализации string
более грамотно управлять ее содержимым.
4.12. Преобразование строки к нижнему или верхнему регистру
Имеется строка, которую требуется преобразовать к нижнему или верхнему регистру.
Для преобразования символов к нижнему или верхнему регистру используйте функции toupper
и tolower
из заголовочного файла . Пример 4.20 показывает, как использовать эти функции. Смотри также обсуждение альтернативных методик.
Пример 4.20. Преобразование регистра строки
#include
#include
#include
#include
#include
using namespace std;
void toUpper(basic_string& s) {
for (basic_string::iterator p = s.begin();
p != s.end(); ++p) {
*p = toupper(*p); // toupper is for char
}
}
void toUpper& s) {
for (basic_string::iterator p = s.begin();
p != s.end(); ++p) {
*p = towupper(*p); // towupper is for wchar_t
}
}
void toLower(basic_string& s) {
for (basic_string::iterator p = s.begin();
p != s.end(); ++p) {
*p = tolower(*p);
}
}
void toLower(basic_string& s) {
for (basic_string::iterator p = s.begin();
p != s.end(); ++p) {
*p = towlower(*p);
}
int main() {
string s = "shazam";
wstring ws = L"wham";
toUpper(s); toUpper(ws);
cout << "s = " << s << endl;
wcout << "ws = " << ws << endl;
toLower(s);
toLower(ws);
cout << "s = " << s << endl;
Интервал:
Закладка: