Программирование. Принципы и практика использования C++ Исправленное издание, стр. 279
print(my_doc);Представление документа в виде последовательности символов полезно по многим причинам, но обычно мы перемещаемся по документам, просматривая более специфичную информацию, чем символ. Например, рассмотрим фрагмент кода, удаляющий строку
nvoid erase_line(Document& d, int n){ if (n<0 || d.line.size()<=n) return; // игнорируем строки, // находящиеся // за пределами диапазона d.line.erase(advance(d.line.begin(), n));}Вызов
advance(p,n)pnadvance()template<class Iter> Iter advance(Iter p, int n){ while (n>0) { ++p; ––n; } // перемещение вперед return p;}Обратите внимание на то, что функцию
advance()vectorv*advance(v.begin(),n)v[n]advance()n–1nlistЕсли итератор может перемещаться вперед и назад, например в классе
listadvance()vectoradvance()++advance()ПОПРОБУЙТЕ
Перепишите нашу функцию
advance()Вероятно, поиск — это самый очевидный вид итерации. Мы ищем отдельные слова (например,
milkshakeGavinsecret\nhomesteadsecrethomestead[bB]\w*neB0ne• Найдем первый символ искомой строки в документе.
• Проверим, совпадают ли эти и следующие символы с символами искомой строки.
• Если совпадают, то задача решена; если нет, будем искать следующее появление первого символа.
Для простоты примем правила представления текстов в библиотеке STL в виде последовательности, определенной парой итераторов. Это позволит нам применить функцию поиска не только ко всему документу, но и к любой его части. Если мы найдем нашу строку в документе, то вернем итератор, установленный на ее первый символ; если не найдем, то вернем итератор, установленный на конец последовательности.
Text_iterator find_txt(Text_iterator first, Text_iterator last, const string& s){ if (s.size()==0) return last; // нельзя искать пустую строку char first_char = s[0]; while (true) { Text_iterator p = find(first,last,first_char); if (p==last || match(p,last,s)) return p; ++first; // ищем следующий символ }}Возврат конца строки в качестве признака неудачного поиска является важным соглашением, принятым в библиотеке STL. Функция
match()find()find_txt()Text_iterator p = find_txt(my_doc.begin(), my_doc.end(),"secret\nhomestead");if (p==my_doc.end()) cout << "Не найдена ";else { // какие-то действия}Наш текстовый процессор и его операции очень просты. Очевидно, что мы хотим создать простой и достаточно эффективный, а не “навороченный” редактор. Однако не следует ошибочно думать, что эффективные вставка, удаление и поиск произвольного символа — тривиальные задачи. Мы выбрали этот пример для того, чтобы продемонстрировать мощь и универсальность концепций последовательности, итератора и контейнера (таких как
listvectorDocumentText_iteratorDocument