Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
34
Добавлен:
23.03.2015
Размер:
787.97 Кб
Скачать

Реализация процедур

Реализация процедуры должна выполнять действия, опреде­ленные в спецификации. В частности, она должна модифицировать только те входные параметры, которые указаны в предло­женииmodifies, а условия в предложенииrequiresдолжны вы­полняться для всех входных значений. Выходные значения должны соответствовать требованиям, указанным в предложе­нииeffects.

Каждый язык программирования имеет свой механизм реали­зации процедурных абстракций. В языке CLUэти абстракции реализуются при помощи процедур CLU,обозначаемых сокра­щенноproc.

На рис. 3.4показаны две процедуры, написанные на языкеCLUи реализующие функциюsearch. Одна из них использует линейный поиск, а вторая —бинарный. Эти две реализации во многом отличаются друг от друга. Например, для всех неболь­ших массивов бинарный поиск быстрее линейного. Кроме этого, если элемент х встречается в массиве а более одного раза, то две процедуры могут -возвратить в качестве результата различные значения индексов. Наконец, если х содержится в массиве а, но сам массив при этом не отсортирован, то процедура, исполь­зующая алгоритм бинарного поиска, может возвратитьhigh(а) + + 1,а другая процедура может отыскать требуемый элемент х (рассмотрим, например, массив а = [1:1, 7, 6, 4, 9)и х == 7). Тем не менее обе процедуры являются корректными реализа­циями абстракцииsearch, поскольку обе они выполняются сог­ласно указанной для них спецификации.

ai = array (int] % аббревиатура

search = proc (a: ai, х: iiit) returns (int)

% реализация с использованием линейного поиска

i: int := ai$low (а)

while i <= ai$high (a) do

if a [i ] = х then return (i) end

if a [i] = x then i := i 4- I else return (ai$high (a) + 1) end

end % конец цикла while

return (i)

end search

search = proc (a: ai, х: int) returns (int)

% реализация с использованием бинарного дерева

low: int := ai$iow (a)

high: int := ai$high (a)

while (low (= high) do

mid: int := (low+ high)/2

val: int := a [mid]

if x (val then high := mid - I

else if x = val then return (mid)

else low := mid + 1

end

end

return (ai$high (a) + 1)

end search

Рис. 3.4.Две реализации процедурыsearch.

В приводимом примере для облегчения прочтения и понимания программы мы придерживались ряда соглашений. Во-первых, мы использовали для формальных параметров те же имена, что и в спецификации. Это соглашение помогает связать реализацию абстракции со спецификацией. За заголовком мы поместили комментарий, поясняющий работу алгоритма. Наконец, мы придер­живались общепринятых правил форматирования.

sort =proc(a:array[int])returns(b:array[int])

effectsВозвращает новый массив с теми же границами, что и а, и содер­жащий элементы из массива а, упорядоченные по возрастанию.merge_sort=proc (a: array [int I, low, high: int) returns (array [int])

requires low (a) <= low <= high <= high (a).

effectsВозвращает новый массив с нижней границей, как и у массива а, и содержащий элементы массиваa[low],...,a[high], расположен­ные в возрастающем порядке.

merge = proc (a, b: array [int]) returns (array [int]) requires Массивы а и b упорядочены по возрастанию.

effectsВозвращает новый массив с тем же значением для нижне.й Гра­нины, что и у массива а, и содержащий элементы массивов а и b,рас­положенные в возрастающем порядке.

Рис, 3.5.Спецификация дляmergesort.

ai =array[int]

sort =proc(a:ai)returns(ai)

%сортировка методом «сортировка слиянием»

if ai$empty (a) then

%создание пустого массива с нижней границейlow(а)

return (ai$create (ai$low (a))

end

return (merge.sort (a, ai$low (a), ai$high (a)))

end sort

merge_sort == proc (a: ai, low, high: int) returns (ai)

if low < high

then % сортировка двух половин и слияние результата

mid: int :== (low + high)/2

return (merge (merge_sort (a, low, mid),

merge_sort(a,mid+I,high)))

else %массив а уже отсортирован, однако мы должны

% возвратить новый массив

b: ai := ai$create (low)

ai$addh (b, a [low])

return (b)

end

end merge _sort

inerge = proc /a, b: ai) returns (ai)

alow: int := ai$low (a) blow: int := ai$low (b)

a_high: int := ai$low (a)

b.high: int :== ai$low (b)

c:ai :=ai$create(alow)% начать снижней границей, равной f_low

%слить а иb

whilealow <=a_highcorbJow <=b_highdo

if alow > a_high cor (blow <= b_high cand b [blow] <a [alow])

then %переслать элемент изbлибо потому, что все элементы из а

%уже переслали, либо потому, что следующий элемент из b

%меньше, чем следующий элемент из а

ai$<iddh (с, b [blow]) blow :== blow+ 1

else%переслать элемент из массива а

ai$addh(с, а [alow])

alow := alow + 1

end

end % конец цикла while

return (с)

endmerge

Рис. 3.6.Реализация метода сортировки слиянием.

В качестве второго примера рассмотрим сортировку массива.. Одним из возможных способов является метод сортировки слия­нием, который сводит задачу к слиянию двух уже отсортирован­ных массивов. Мы начинаем с деления массива на две части, за­тем сортируем каждую из них и объединяем результаты:%сортировка первой половины массива%сортировка второй половины массива%объединение двух отсортированных частей. Для выполнения этих шагов используем две дополнительные про­цедуры: процедуруmergeдля операции слияния и процедуруmerge_sortдля сортировки каждой части массива. Процедураmerge_sortвыполнит эти же три шага для частей массива, реали­зуя рекурсивный алгоритм.

На рис. 3.5показаны спецификации для процедурыsortи двух вспомогательных абстракций. Отметим, что процедураsortне модифицирует входной массив, а процедурыmergeи merge_sort являются частичными. На рис. 3.6приведены процедурыCLU, реализующие данные абстракции.

Соседние файлы в папке Программы