Если бы документ хранился как объект класса vector, перемещаться по нему было бы просто. Как перемещать итератор по списку строк? Очевидно, что перемещаться по списку можно с помощью класса list::iterator. Однако, что, если мы хотим пройтись по символам один за другим, не беспокоясь о разбиении строки?
Также возможно вы думаете, что такая тема как http://brain8torm.ru/services/website-development.html никак не связана и даже не тематична с программированием. Хотя, может быть и связана, ведь создание сайтов - это отчасти программирование.
Возможно, это и так, но все-таки зайдите на сайт brain8torm.ru - там можно узнать много интересного про то, где есть создание сайтов в твери. Что означает создание сайтов в твери, за сколько денег возможно создание сайтов в твери - про это написано на сайте brain8torm.ru. Это важная для многих тема - создание сайтов в твери. Спасибо сайту brain8torm.ru за информацию про то, где есть создание сайтов в твери
Мы могли бы использовать итератор, специально разработанный для нашего класса Document.
class Text_iterator { // отслеживает позицию символа в строке list::iterator ln;
Line::iterator pos; public:
// устанавливает итератор на позицию pp в ll-й строке Text_iterator(list::iterator ll, Line::iterator pp) :ln(ll), pos(pp) { }
char& operator*() { return *pos; }
Text_iterator& operator++();
bool operator==(const Text_iterator& other) const { return ln==other.ln && pos==other.pos; }
bool operator!=(const Text_iterator& other) const { return !(*this==other); }
};
Text_iterator& Text_iterator::operator++()
{
if (pos==(*ln).end()) {
++ln; // переход на новую строку
pos = (*ln).begin();
}
++pos; // переход на новый символ
return *this;
}
Для того чтобы класс Text_iterator стал полезным, необходимо снабдить класс Document традиционными функциями begin() и end().
struct Document {
list line;
Text_iterator begin() // первый символ первой строки { return Text_iterator(line.begin(), (*line.begin()).begin()); }
Text_iterator end() // за последним символом последней строки { return(line.end(), (*line.end()).end));}
};
Мы использовали любопытную конструкцию (*line.begin()).begin(), потому что хотим начинать перемещение итератора с позиции, на которую ссылается итератор line.begin(); в качестве альтернативы можно было бы использовать функцию line.begin()->begin(), так как стандартные итераторы поддерживают операцию ->.
Теперь можем перемещаться по символам документа. void print(Document& d)
{
for (Text_iterator p = d.begin(); p!=d.end(); ++p) cout << *p;
}
print(my_doc);
Представление документа в виде последовательности символов полезно по многим причинам, но обычно мы перемещаемся по документам, просматривая более специфичную информацию, чем символ. Например, рассмотрим фрагмент кода, удаляющий строку n.
void 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) перемещает итератор p на n элементов вперед; функция advance() — это стандартная функция, но мы можем сами написать подобный код.
template Iter advance(Iter p, int n)
{
while (n>0) { ++p; —n; } // перемещение вперед return p;
}
Обратите внимание на то, что функцию advance() можно использовать для имитации индексирования. Фактически для объекта класса vector с именем v выражение *advance(v.begin(),n) почти эквивалентно конструкции v[n]. Здесь слово “почти” означает, что функция advance() старательно проходит по каждому из первых n—1 элементов шаг за шагом, в то время как операция индексирования сразу обращается к n-му элементу. Для класса list мы вынуждены использовать этот неэффективный метод. Это цена, которую мы должны заплатить за гибкость списка.
Опубликовал katy
April 22 2015 21:17:09 ·
0 Комментариев ·
2881 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.