- •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) %расширить s0-ми до верхней границы 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.