- •4.9.1. Изменяемость
- •4.9.2. Классы операций
- •98 Глава 4
- •4.9.3. Полнота
- •100 Глава 4
- •4.9.5. Операции egual, similar и copy
- •102 Глава 4
- •104 Глава 4
- •5. Исключительные ситуации
- •108 Глава 5
- •110 Глава 5
- •6.2.1. Сигнализация об исключительных ситуациях
- •5.2.2. Обработка исключительных ситуаций
- •112 Глава 5
- •5.2.3. Предложение resignal
- •6.2.4. Необрабатываемые исключительные ситуации
- •114 Глава 5
- •6.2.3. Предложение resignal
- •5.2.4. Необрабатываемые исключительные ситуации
- •116 Глава 5
- •118 Глава 5
- •118 Глава 5
- •120 Глава 5
- •122 Глава 5
- •124 Глава 5
- •128 Глава 6
- •130 Глава 6
- •6.2.1. Реализация итераторов
- •6.2.2. Использование итераторов
- •132 Глава 6
- •134 Глава 6
- •136 Глава 6
- •138 Глава 6
- •140 Глава 7
- •142 Глава 7
- •7.2. Абстракция данных
- •144 Глава 7
- •146 Глава 7
- •148 Глава 7
- •150 Глава 7
- •7.4. Генераторы
- •162 Глава 7
- •154 Глава 7
- •156 Глава 7
- •162 Глава 8
- •164 Глава 8
- •166 Глава 8
- •168 Глава 8
- •170 Глава 9
- •172 Глава 9
- •174 Глава 9
- •176 Глава 9
- •9.1.3. Пример
- •178 Глава 9
- •180 Глава 9
- •182 Глава 9
- •184 Глава 9
- •186 Глава 9
- •188 Глава 9
- •190 Глава 9
- •192 Глава. 9
- •194 Глава 9
134 Глава 6
примером рис. 6.9:
является итератор permuta-
node== record [val: t, left, right: olist [t]] rep = variant [some: node, empty: null] small _to_big= Her (s: cvt) yields (t) tagcase s tag empty: return tag some (n: node): for e; t in small_to_big (n.left) do % выдать элементы левого поддерева yield (e) end yield (n.val) for e: t in small_to_big (n.right) do % выдать элементы правого поддерева yield (e) end end end small_to_big Рис. 6.8. Операция small, to_ big для упорядоченного списка.
Нашим следующим tions, приведенный на
si = sequence (int) permutations = iter (seq: si) yields (si)
% если последовательность состоит из одного числа, то оно выдается, и организуется выход if si$size (seq) = I then yield (seq) else for index: int in si$indexes (seq) do % Создать некоторую последовательность, в которой опущено значение
с этим индексом val: int;=seq [index] prefix: si :== si$subseq (seq, I, index — 1) suffix: si :=si$subseq (seq, index+ I, si$size (seq)) % Присоединить перестановки последовательности к этому значению
и выдать
for perm: si in permutations (prefix Ц suffix) do % Операция II является операцией конкатенации yield (si$addl (perm, val)) end % конец для perm end % конец для index end % конец для if end permutations Рис. 6.9. Итератор permutations.
permutations' iter (seq: sequence [int]) yields (sequence [int]) effects Выдает в произвольном порядке все последовательности, построенные при помощи перестановок элементов в наборе seq.
Данная реализация использует итератор последовательностей indexes. При работе этот итератор выдает все перестановки, которые получаются, если зафиксировать на первом месте первый элемент первоначальной последовательности, затем зафиксировать на первом месте второй элемент первоначальной последовательности и т. д. Для того чтобы получить перестановки с зафиксированным на первом месте п-ным элементом, создается некоторая последовательность, содержащая все другие элементы, и
\ракция итерации
_полняются перестановки этой последовательности, обращаясь рекурсивно к самому себе. Затем п-ный элемент добавляется ^ к началу каждой перестановки последовательности и выдается результирующая последовательность.
Нашим последним примером является итератор allprimes, приведенный на рис. 6.10.
ai = array [int] allprimes = iter ( ) yields (int) yield (2) % выдается первое простое число primes: ai :== ai$new ( ) x: int := I while true do
x: = x+2 % следующее рассматриваемое число for p: int in ai$elements (primes) do if x//p == 0 then exit not_found end
% x—не простое число
if piiip^x then break end % x — простое число end except when not_found: continue end % имеем некоторое простое число yield (x) ai$addh (primes, x) end end primes Рис. 6.10. Итератор allprimes.
allprimes =: iter ( ) yields (int) effects Выдаются простые числа в возрастающем порядке.
В нашей реализации все найденные до некоторого момента простые числа Хранятся в массиве primes. В цикле while получаются нечетные числа. Те из них, которые кратны ранее найденным простым числам, отбрасываются в цикле for. Мы останавливаем цикл for, как только достигаем некоторого простого числа, чей квадрат больше текущего рассматриваемого числа, поскольку это рассматриваемое число не может, по-видимому, делиться на большее простое число.
6.4. Вопросы проектирования
Итераторы будут включаться среди других операций в большинство типов данных, особенно в такие типы, как intset и olist, чьи объекты являются совокупностями других объектов. Итераторы часто необходимы для полноты — они позволяют организовать доступ к элементам некоторой совокупности таким способом, который эффективен и удобен.
Тип может иметь несколько итераторов. Например, упорядоченные списки olist могли бы иметь такую операцию:
big.to.small = iter (s: olist [t]) yields (t) requires чтобы набор s не модифицировался в теле цикла. effects Выдает элементы набора s в порядке уменьшения, как это определяется при помощи операции t$lt, причем каждый элемент только один раз.
