- •1. Введение
- •1.1. Декомпозиция и абстракция
- •1.2. Абстракция
- •1.2.1. Абстракция через параметризацию
- •1.2.2. Абстракция через спецификацию
- •1.2.3. Виды абстракций
- •3. Процедурная абстракция
- •3.2. Спецификации
- •3.3. Спецификации процедурных абстракций
- •3.4. Реализация процедур
- •3.5. Более обобщенные процедуры
- •3.6. Создание процедурных абстракций
- •3.7. Заключение
- •4. Абстракции данных
- •4.1. Спецификации для абстракций данных
- •4.2.1. Реализация на языке clu
- •4.2.2. Замечания по поводу операций up и down
- •4.3. Использование абстракций данных
- •4.4. Реализация полиномов
- •4.5. Пояснения для понимания реализаций
- •4.5.1. Функция абстракции
- •4.5.2. Инвариант представления
- •4.6.3. Сохранение инварианта представления
- •4.5.4. Изменяемые представления
- •4.6. Параметризованные абстракции данных
- •4.7. Списки
- •4.8. Упорядоченные списки
4.4. Реализация полиномов
В следующем примере мы реализуем тип данных poly. Спецификация этого типа представлена на рис. 4.3. Полиномы могут быть представлены массивами, в которых i-му элементу массива соответствует коэффициент при i-м члене полинома. В массивах хранятся коэффициенты только для членов, степень которых не выше степени полинома; хранить коэффициенты при более старших членах необходимости нет (поскольку все они равны нулю). Точно так же, мы не храним младшие нулевые коэффициенты, и нулевой полином представляется пустым массивом. Если нижняя граница этого массива равна нулю, то его верхняя граница всегда будет равна степени полинома. Если между младшим и старшим ненулевыми членами полинома мало членов с нулевыми коэффициентами, то это представление удачно, если же нет, как, например, у полинома х + х^, то неудачно, так как в мас^ сиве будет храниться много нулей.
Кластер, использующий это представление, показан ^ Р^- 4-7. ро1у= cluster is create, degree, coeff, add, minus, mul, sub, е-Ч"^ rep == array [int ]
create = proc (c, n: int) returns (cvt) if с = 0 then return (rep$new ( )) end % нулевой полином r: rep := rep$create (n) % степенью будет нижн. и верх. гра. нипа rep$addh (r, с) % добавить ненулевой коэффициент return (r) end create
degree = proc (p: cvt) returns (int) return (rep$high (p)) end degree
coeff == proc (p: cvt, n: int) returns (int) If n )rep$high (p) cor n (rep$low (p)
then return (0) else return (p [n]) end end coeff
add = proc (p, q: cvt) returns (cvt) % сделать p полиномом с началом у нижней границы if rep$low (q) (rep$low (p) then p, q := q, p end s: rep :^= rep$copy (p) % инициализировать s в p qhigh: int := rep$high (q) % расширить s 0-ми до верхней границы q while rep$high (s) (qhigh do rep$addh (s, 0) end
i: int :=== rep$low (q)
while i (= qhigh do % прибавить коэфф. q к s s [i] := s [i]+q [i] i:=i+ I end
while — rep$empty (s) do % удалить лишние нули справа и слева if rep$bottom (s) = 0 then rep$reml (s) elseif rep$top (s) = 0 then rep$remh (s) else return (s) end end
return (rep$new ( )) % нулевой полином end add
minus = proc (p: cvt) returns (cvt) i: int := rep$low (p) q: rep ;= rep$create (i) while i (= rep$high (p) do rep$addh (q, —p [i]) i:=i+ I end return (q) end minus
sub = proc (p, q: poly) returns (poly) return [p+ (~q)) % используются короткие формы end sub
mul = proc (p, q: cvt) returns (cvt) % проверка на умножение на нуль if rep$empty (p) cor rep$empty (q) then return (rep$new ( )) en»
Абстракции данных
&: rep := rep$create (rep$low (p) + rep$low (q))
% создание s с новой нижней границей
shigh: int := rep$high (p) + rep$high (q) % новая верхняя граница while rep$high (s) (shigh do % записать в s нули rep$addh (s, 0) end i: int := rep$low (p) phigh: int := rep$high (p) qlow: int := rep$low (q) qhigh: int := rep$high (q)
while i (= phigh do % осуществить умножение j: int := qlow while j (= qhigh do s [i+jl := s [i+jl+ P li] *q Ш j^j+l end i:=i+ I end return (s) endi mul
equal = proc (p, q: cvt) returns (bool) return (rep$similar (p, q)) end equal
end poly Рис. 4.7. Реализация типа данных poly.
Для этого представления легко реализуются операции create, degree и coeff. Операция create возвращает либо пустой массив (который представляет нулевой полином), либо массив с одним элементом, содержащий заданный коэффициент. Операция degree возвращает верхнюю границу массива; таким образом, она предполагает, что эта граница равна степени полинома. Выполнение этого требования гарантируется операцией create и операцией add, которая после произведения необходимых действий удаляет все лишние нули. Выполнение этого требования также гарантируется операцией mul, так как нули в старших или младших членах могут возникнуть, только если один из вводных полиномов нулевой, этот же случай обрабатывается явно.
Операция equal просто обращается к операции similar для массивов, а эта операция возвращает значение true, если ее параметры имеют одинаковые нижние границы и одинаковые (одинаковым образом расположенные) элементы, что нам как раз и требуется. Заметим, что операция equal для массивов не годится, так как она возвращает значение true, только если два ее вводных массива являются одним и тем же объектом.
Имена операций над полиномами были выбраны так, чтобы они были достаточно коротки и удобны. Например, для операции add может использоваться р+q, а для операции minus может использоваться —р. Эти короткие формы используются при реализации операции sub.
