
- •6. Абстракции данных
- •6.1 Представление рациональных чисел
- •6.1.1 Первое внутреннее представление рациональных чисел
- •6.1.2 Второе внутреннее представление рациональных чисел
- •6.1.3 Функциональный тип данных
- •6.1.4 Третье внутреннее представление рациональных чисел
- •6.2 Представления множеств
- •6.2.1 Функции над множествами. Определения
- •6.2.2 Представление множеств списками
- •6.2.2.1 Неупорядоченные множества
- •6.2.2.2 Упорядоченные множества
- •6.2.3 Представление множеств двоичными деревьями
- •6.2.4 Представление древовидных структур
6. Абстракции данных
6.1 Представление рациональных чисел
Абстракция данных - достаточно популярная методология программирования.
Основная идея состоит в том, чтобы отделить способ использования данных от подробностей того, каким образом они реализованы или созданы, подобно тому, как функциональная абстракция разделяет способ применения функции и детали её реализации даже в терминах более примитивных функций.
Для достижения этой цели программы должны использовать составные данные таким способом, чтобы не делать никаких предположений о внутренней структуре этих данных, кроме тех, которые принципиально необходимы для решения задачи.
Другими словами, программы должны работать с абстрактными объектами данных.
Для этого необходимо для каждого типа данных, определить набор базовых операций, в терминах которых выражаются все операции с объектами данных этого типа. И когда программы, манипулирующие данными, станут использовать только эти операции, цель будет достигнута.
В то же время конкретное представление данных должно быть определено независимо от программ, которые используют эти данные. Подобно тому, как мы можем заменить процедуру (по-другому – алгоритм) любой другой процедурой, использующей ту же самую функцию, мы можем заменить представление объектов данных любым другим представлением, реализующим тот же самый тип данных.
Давайте рассмотрим в качестве примера набор операций с рациональными числами.
П
n1
n2
---
---
d1
d2
редположим,
что нам необходимо только складывать,
вычитать, умножать, делить и сравнивать
рациональные числа. Как известно, каждое
рациональное число, например, r
определяется парой целых чисел –
числителем(n)
и знаменателем(d),т.е.
r
= n/d,
а действия с этими числами совершаемые,
обычно определяются как действия с
соответствующими числителями и
знаменателями:
выражения числитель знаменатель
r1 ± r2 n1*d2 ± n2*d1 d1*d2
r1 * r2 n1*n2 d1*d2
r1 / r2 n1*d2 n2*d1
r1 = r2 iff n1*d2 = d1*n2
При реализации этих правил, абстракция рационального числа должна будет воплотится в трех функциях.
Создание каждого рационального числа будет результатом функциии-конструктора (make-rat n d), а чтобы иметь доступ отдельно к числителю и знаменателю рационального числа r должны быть функции-селекторы для числителя (числитель r) и знаменателя (знаменатель r).
Теперь в терминах этих функций мы можем определить основные операции арифметики рациональных чисел, например, так:
> (define (add-rat r1 r2)
(make-rat (+ (* (числитель r1)(знаменатель r2))
(* (числитель r2)(знаменатель r1)))
(* (знаменатель r1)(знаменатель r2))))
> (define (sub-rat r1 r2)
(make-rat (- (* (числитель r1)(знаменатель r2))
(* (числитель r2)(знаменатель r1)))
(* (знаменатель r1)(знаменатель r2))))
> (define (mul-rat r1 r2)
(make-rat (* (числитель r1)(числитель r2))
(* (знаменатель r1)(знаменатель r2))))
> (define (div-rat r1 r2)
(make-rat (* (числитель r1)(знаменатель r2))
(* (числитель r2)(знаменатель r1))))
> (define (eq-rat? r1 r2)
(= (* (числитель r1)(знаменатель r2))
(* (числитель r2)(знаменатель r1))))
Для изучения получаемых чисел можно добавить функцию вывода.
> (define (display-rat r)
(display '=)
(display (числитель r))(display '/)(display (знаменатель r))
(newline))