
- •Понятие данных
- •Информация и данные. Понятие о структурах данных. Информационная модель объекта
- •Понятие о данных
- •Понятие о структурах данных
- •Структуры данных и их классификация (списки, таблицы, деревья, сети).
- •Таблицы
- •Деревья
- •Понятие о типе данных в языках программирования
- •14101954
- •6. Понятие о типе данных в языках программирования (яп).
- •Декомпозиция и абстракция, их применение в программировании.
- •Абстракция и декомпозиция. Их взаимодействие при проектировании программ.
- •Абстракция – это отвлечение от всего несущественного с целью лучше понять какую-либо одну строну изучаемого предмета или явления, и в тоже время – это путь к созданию абстрактных понятий.
- •15. Реализация абстракций данных . Функция абстракции. Операции Up и Down.
- •Функция абстракции
- •Функция инвариант представления
- •Сохранение инварианта представления
- •Анализ программ, не содержащих ветвлений
- •Если p{ а }q и q{ b }r, то выполняется p{ a;b }r.
- •P{ a;b }r.
- •Проектирование цикла с помощью инварианта Задача 1. Найти сумму величин 1/I от 1 до тех пор, пока она не станет больше некоторого наперед заданного числаa.
- •Будем искать решение нашей задачи в виде цикла, имеющего следующий вид:
Функция абстракции
Любая реализация абстракции данных должна определять, как представляются объекты, принадлежащие к этому типу. Выбирая представление, тот, кто занимается реализацией, учитывает связь между объектами представления и абстрактными объектами. Предполагается, что определенные объекты представления будут соответствовать, определенным абстрактным объектам.
Эта взаимосвязь может быть определена функцией, которая называется функцией абстракции. Эта функция отображает объекты представления в абстрактные объекты:
Здесь А обозначает набор абстрактных объектов. Для каждого объекта представления r, А(r) является абстрактным объектом аA, который представляет r.
А: rep А
Рис. 1. Пример
функции абстракции.
Функция абстракции – это важнейшая информация о реализации. Она определяет конкретное представление, т.е. то, каким образом объекты представления реализуют абстрактные объекты. Эта функция должна быть обязательно представлена в комментариях реализации. Описывая функцию реализации, мы иногда сталкиваемся с проблемой, связанной с тем, что, если спецификация типа неформальная, область изменения функции абстракции не может быть точно определена. Сейчас мы будем преодолевать эту проблему с помощью неформального описания «типичного» абстрактного объекта.
Для определения функции абстракции прежде всего определяем типичный элемент абстрактного типа. Это дает нам возможность говорить об абстрактных объектах. Затем можем определить функцию абстракции в терминах этого типичного объекта. Например, для наборов intset вы можете дать следующее описание:
Типичный набор intset есть {х1, ... хn}
Здесь для описания наборов intset используем понятие математического набора, точно так же, как делали это в спецификации intset. Затем пишем
/*Функция абстракции есть
А(r) = {r[i] | low(r) i high(r)},
*/
где {x | p(x)} есть набор всех таких х, что р(х) имеет значение true.
В качестве другого примера рассмотрим полиномы. Мы решаем представлять полином массивом, в котором i-й элемент содержит i-й коэффициент, если этот коэффициент не относится к нулевым коэффициентам справа или слева от значащих членов полинома. Это представление описываем следующим образом:
/*Типичный полином есть: c0 + c1x + c2x2+ ...
Функция абстракции для коэффициента с1 есть
ci = г [i], если low(r) i high (r)
= 0 в противном случае
*/
Эта функция абстракции определена только для массивов с неотрицательной нижней границей. Функции абстракции часто имеют заданные области определения, как, например, в рассматриваемом случае.
Функция абстракции, в частности, удобна тем, что устраняет двусмысленности в интерпретации представления. Например, предположим, что с помощью массивов мы реализуем стеки. Мы можем выбирать, каким образом увеличивать массив, когда в стек добавляется новый элемент. Этот наш выбор будет отражен в функции абстракции. Если вы решаете увеличивать старший индекс массива и по этому индексу записывать элемент, то функция абстракции будет следующая:
/*Типичный стек – это последовательность [е1,...,еn], где
еn – элемент со старшим индексом
Функция абстракции есть
А(г) = [r[low (r)], ..., r [high (r)]]
Если вы решаете уменьшать младший индекс и по этому индексу записывать элемент, то
А(r) = [r[high(r)], ..., r[low(r)]]
*/
Заметим, что реализации стеков, о которых только что говорилось, используют одно и то же представление, которое интерпретируется, однако, по-разному.
Пример функции абстракции для стека
╔════════════════════════════════════════════════════════╗
║ Дескриптор стека REP(Представление стека) ║
║ ┌────────────┐ ========================= ║
S1─────╫─>│Size│ ║
║ ├────────────┤ ║
║ │ TopInd│ ║
║ ├────────────┤ ║
║ │ PBody│ ║
║ └─────┼──────┘ ║
║ │ ║
║ ┌─────┼─────────────────────────────────────────────┐ ║
║ │ │ Тело стека │ ║
║ │ │ ┌───────────┐ │ ║
║ │ │ Size│-----------│ │ ║
║ │ │ ├───────────┤ │ ║
║ │ │ ...│-Свободно--│ │ ║
║ │ │ ├───────────┤ │ ║
║ │ │ │-----------│ │ ║
║ │ │ ├───────────┤ │ ║
║ │ │ TopInd│///////////│ Вершина │ ║
║ │ │ ├───────────┤ │ ║
║ │ │ ...│///////////│ │ ║
║ │ │ ├───────────┤ │ ║
║ │ │ 3 │/Заполнено/│ │ ║
║ │ │ ├───────────┤ │ ║
║ │ │ 2 │///////////│ │ ║
║ │ │ ├───────────┤ │ ║
║ │ └────────> 1 │///////////│ │ ║
║ │ └───────────┘ │ ║
║ │ ////////////////////// │ ║
║ │ //// Дно стека //// │ ║
║ └───────────────────────────────────────────────────┘ ║
╚════════════════════════════════════════════════════════╝
=================================== Тищенко =============================
Вопрос № 16 :
Реализация абстракции данных. Функция инвариант представления. Сохранения инварианта представления.
Для реализации типа данных мы выбираем представление для объектов и реализуем операции в терминах этого представления. Выбранное представление должно предоставлять возможности для довольно простой и эффективной реализации всех операций. Кроме того, если некоторые операции должны выполняться быстро, представление должно предоставлять и эту возможность. Часто представление, обеспечивающее быструю работу некоторых операций, приводит к тому, что другие операции выполняются медленно. В этом случае мы должны использовать несколько различных реализаций одного и того же типа.
Например, возможное представление для объекта intset — это массив целых чисел, где каждое целое число набора intset соответствует элементу массива. Мы должны решить — должен ли каждый элемент набора встречаться в массиве только один раз или же он может встречаться много раз. В последнем случае операция insert будет работать быстрее, однако операции delete и member будут выполняться медленнее. Если операция member используется часто, мы должны остановиться на первом случае.
Заметим, что здесь мы говорим о двух разных типах: новом абстрактном типе intset, который мы реализуем, и массиве целых, который используется как представление. Каждая реализация будет иметь два таких типа: абстрактный тип и тип представления (rep type). Предполагается, что с типом представления мы имеем дело только при реализации. Все, что мы можем делать с объектами абстрактного типа, — это применять к ним соответствующие данному типу операции. Соблюдение этого ограничения в языке CLU осуществляется с помощью контроля типов. Язык CLU удобен, поскольку в нем тип может быть реализован как отдельный программный модуль. Эта программная единица языка CLU называется кластер. Отсюда и название (CLU от слова CLUster.)
Внутри кластера должны быть доступны как абстрактный тип, так и тип представления. Более того, должна иметься возможность перехода от одного типа к другому. Например, операция insert получает в качестве аргумента набор целых чисел, но для реализации insert необходимо использовать массив, который представляет этот набор.
Возможность перехода от абстрактного типа к типу представления и обратно в языке CLU обеспечивают две специальные операции: up и down. Операция up использует в качестве аргумента объект представления и в качестве результата выдает абстрактный объект, а операция down осуществляет обратное действие. Для того чтобы обеспечить преобразование абстрактного типа в тип представления и обратно, каждый кластер имеет свою собственную версию операций up и down. Эти операции автоматически определяются компилятором CLU. Например, в кластере процедуры intset компилятор порождает операции up и down со следующими заголовками:
up = proc (a: array [int]) returns (intset) down = proc (s: intset) returns (array [int])
Операции up и down могут использоваться только в кластерах и всегда осуществляют переход от абстрактного типа к типу представления и обратно только для кластера, в котором они появились. Поэтому операции up и down не могут отрицательно повлиять на контроль типов языка CLU.