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

Иванова Г.С. - Основы программирования

.pdf
Скачиваний:
2771
Добавлен:
02.04.2015
Размер:
13.53 Mб
Скачать

5. Модульное программирование

(

Начало j

Г

Начало

j

 

Ввод

/

Ввод

Т

 

m

 

 

 

 

i=l,m,l

 

a=(I,l,l,

 

 

1,1,1,1,1,1,1)

 

 

 

 

 

a[l] = i

 

 

 

К

J=b"^»i

 

Вывод

/

 

 

 

a(n)

/

/

a[21=j

k=l,m,l

a[3] = k

n=I,m,I

a[4] = n

Вывод /

a(4) /

/

{Конец J

Рис. 5.18. Два варианта алгоритма генерации комбинаций:

а-с использованием вложенных циклов;б-программно-реализуемый счет^шк

Program ex; Const

a:array[L, 10] ofbyte^d 7,7,7,7,7,7,7,7,7;; Fbr Im^n:integer;

181

Рис. 5.19. Представление дан­ ных для задачи о ферзях

Часть I. Основы алгоритмизации и процедурное программирование

Begin ReadLn(ri,m);

while aflj<m+l do {условие «сброса» счетчика} begin

for i:=] to n do Write(a[i]); (вывод комбинации} WriteC У;

a[n]:=afnj+l; {добавление 1 в последний разряд}

for i:=n downto 2 йЬ{анализ и осуществление переносов} ifa[i]>m then

begin afij:=l;

a[i'l]:^a[i'l]+l:

end;

end End

Ассоциируя комбинации счетчика с вариантами данных и проверяя по­ лученные комбинации по критериям конкретной задачи, можно осуществить полный перебор вариантов.

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

Пример 5.18. Задача о расстановке ферзей. Разработать программу, ко­ торая формирует все возможные варианты расстановки m (m>3) ферзей на шахматной доске mxm клеток, при которых ферзи не «бьют» друг друга.

Начнем с выбора способа представления данных задачи. С первого взгляда кажется, что доска должна представляться матрицей, а местоположе­ ние ферзей - размещением символов «*» в матрице. Однако заметим, что го­ раздо удобнее вариант, при котором доска представлена вектором. Индекс вектора в таком представлении соответствует номеру столбца доски, а значе­

1 2 3 4

 

 

 

ние - номеру строки, в которой располо­

 

 

 

жен ферзь (рис. 5.19).

 

*

 

 

 

Определим,

что для

векторного

*

(=:0> 1 3

I 1 4 |

2 |

представления означает «бьет». Ферзь j

*

«бьет» ферзь i, если они расположены на

*

1 2

3

4

одной диагонали,

вертикали

или гори­

зонтали. При векторном представлении шахматной доски расположение на од­ ной вертикали невозможно, следователь­ но, необходимо проверять два условия:

182

{добавление единицы в младший разряд счетчика}
{обработка переносов}

5. Модульное программирование

pole[j] = poIe[i] - одна горизонталь;

I Pol^LJ] " pole[i] I =1 j - i I - одна диагональ.

Для определения всех вариантов расстановок ферзей, удовлетворяющих условию задачи, необходимо проверить все возможные варианты расстано­ вок.

Полный перебор. Полный перебор будем реализовывать в соответствии с алгоритмом, описанным в начале данного раздела. Ниже приведена про­ грамма, реализующая стратегию полного перебора для данной задачи. Она включает две функции: функцию генерации вариантов расстановки и функ­ цию проверки комбинации.

Функция генерации вариантов возвращает в точку вызова булевское зна­ чение: true - если еще есть варианты, false - если просмотрены все вариан­ ты. Следующий вариант расстановки возвращается через параметр-перемен­ ную pole.

Функция проверки комбинаций для каждых двух ферзей на доске прове­ ряет условие «бьет». Если хотя бы один раз это условие выполняется, то дан­ ный вариант не является решением.

Program ex;

Type p=arrayfl.. 100] of integer; Var pole.'p;

i,m:integer;

{функция проверки комбинации}

Function newj-(m:integer;pole:p).boolean; Var iJ: integer;

Begin new_r:=false;

for i:=I to m-J do forj:=i+l to m do

if(pole[i]='polelj]) or(abs(polelj]'pole[i])==j'i) then exit; new_r:-true;

End;

{функция генерации вариантов}

Function Variantfm:integer; Var pole:p):boolean; Var i:integer;

Begin polefmJ:=pole[mJ+I;

for i:=m downto 2 do ifpole[i] > m then

begin pole[i]:=l;

polefi'l]: =^polefi'IJ+1;

end;

183

Часть I. Основы алгоритмизации и процедурное программирование

ifpoIefJJ <=т then {если есть еще варианты}

Variant: =true else Variant:'='false;

End;

{основная программа}

Begin

WritelnCВведите размер

доски');

ReadLn(m);

 

for i:=l to m dopole[i]:=l;

{исходная комбинация}

repeat

 

if Newr(m,pole) then

{проверяем расстановку}

begin

for i:=l to m do Write(pole[i]:2); Writein;

end;

until not Variant(m,pole); {если есть варианты, то генериру­ ем новый вариант}

End

Недостаток полного перебора, как уже говорилось выше, заключается в том, что вычислительная сложность данного решения составляет 0(т"^).

Ограниченный перебор, реализованный с использованием рекурсии. Для генерации комбинаций будем использовать древовидную рекурсию, на каж­ дом уровне которой ставится один ферзь m различными способами. При этом появляется возможность проверки перспективности уже имеющейся комбинации. Поясним сказанное на примере доски 4x4.

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

]..., 2...,3...,4....

На втором шаге второго ферзя можно поставить на одно из четырех по­ лей второго вертикального ряда. При этом мы получим 4 комбинации для каждого варианта установки первого ферзя:

11.., 12.., 13.., 14.. 21.., 22.., 23.., 24..

31.., 32.., 33.., 34..

41.., 42.., 43.., 44..

На этом этапе уже можно исключить все варианты, для которых первые два ферзя «бьют» друг друга: 11.., 12.., 21.., 22.., 23.., 32.., 33.., 34.., 43.., 44.. Генерацию остальных комбинаций необходимо продолжить, установив тре­ тьего ферзя одним из четырех способов и исключив неперспективные реше­ ния. На последнем этапе необходимо установить четвертого ферзя и опять

184

5, Модульное программирование

1421

1422

1423

1424

2411 2412 2413

2414

Рис.5.20. Дерево вариантов с отсечением неперспективных ветвей

исключить варианты, в которых ферзи бьют друг друга. Оставшиеся вариан­ ты являются решениями задачи.

На рис. 5.20 показан фрагмент дерева генерации вариантов для m = 4 с отсечением неперспективных ветвей. Первое найденное решение - комбина­ ция 2413.

На рис. 5.21 показаны алгоритм основной программы, ре1о^рсивной под­ программы добавления ферзя ferz и функции проверки перспективности по­ лученной комбинации new_r, а ниже приведена соответствующая програм­ ма.

Program ex;

Type p=arrayfl.. lOOJ ofinteger; Varpole:p;

km:integer;

{функция проверки перспективности комбинации}

Function new_r(n:integer;poIe:p):boolean; Varj:integer;

Begin newjr:-false; for j:-l to n-1 do

if (polelj]'='pole[n])or(abs(pole[j]-pole[n])=n-j) then exit; newJ*:-true;

End;

{рекурсивная функция генерации комбинации}

Procedureferz(n,m:integer; varpole:p); Var i:integer;

185

Часть 1. Основы алгоритмизации и процедурное программирование

 

 

 

newr "\

V(n,m,pole)y

 

 

 

C(n,pole) J

 

(

Начало

j

new r=true

 

 

 

/

Ввод

У

 

 

L—JZ—J

 

 

ferz (l,m,poIe)

Г Конец j

Рис. 5.21. Алгоритмы основной программы {а), функции проверки перспективности полученной комбинации (б)

и рекурсивной процедуры добавления ферзя {в)

Begin

ifn=m+I then {если установлено m ферзей, то вывести решение} begin

for i:=J to m do Write(pole[ij: 2); WriteLn;

end

else {иначе - пытаемся установить следующего ферзя} for i:=I to m do {m способами}

begin

pole[nJ:=i; {установка п-го ферзя}

if new_r(n,pole) {проверка перспективности комбинации} thenferz(n'^l,m,pole); {рекурсивный вызов установки

следующего ферзя}

end;

End;

{основная программа}

Begin

WriteLn('Beedume размер доски: *); ReadLn(m);

186

 

5. Модульное программирование

 

 

 

 

Т а б л и ц а 5.1

 

Количество вариантов,

Количество вариантов,

Количество

Размер доски

которое проверяется

рассмотренных при

полученных

 

при полном переборе

ограниченном переборе

решений

4x4

44 = 256

17

2

5x5

55 = 3125

54

10

6x6

66 = 46656

153

4

7x7

V = 823543

552

40

8x8

88=16777216

2057

92

к:=0;

ferz(hmypole);

End,

Процедуру new_r используют для проверки уже сгенерированной ком­ бинации (уровень п соответствует попытке установить п-го ферзя). Процеду­ ра ferz рекурсивна. На каждом уровне она может породить до m рекурсивных вызовов (в соответствии с деревом генерации вариантов). Однако общее ко­ личество рассматриваемых вариантов резко уменьшается, так как неперспек­ тивные комбинации отсекаются, что наглядно представлено в табл. 5.1.

Задания для самопроверки

Задание I. Разработайте рекурсивную подпрофамму, осуществляющую поиск комбинации для отпирания кодового замка по методу перебора с отсечением непер­ спективных комбинаций. Замок представляет собой набор из п переключателей, каж­ дый из которых может находиться в положении «включено» или «выключено». За­ мок открывается при одном положении переключателей, причем в положении «включено» может находиться не более половины переключателей.

Задание 2. Разработайте рекурсивную подпрограмму, которая формирует из за­ данного списка предметов определенной стоимости и веса набор, вес которого не превышает заданного, а стоимость максимальна.

187

6. ФАЙЛОВАЯ СИСТЕМА, ФАЙЛЫ

Файлам называют именованную последовательность элементов данных (компо­ нент файла), расположенных, как правило, во внешней памяти: на дискетах, винчестере, CD или других устройствах хранения информации, также устройствах ввода-вывода. В файле может храниться текст, программа, числовые данные, фафическое изображение и т.д. Для организации работы с файлами профамма на Borland Pascal взаимодействует с операционной системой MS DOS.

6.1. Файловая система MS DOS

Как сказано выше, каждый файл обязательно имеет имя. Имена файлов

вMS DOS подчиняются определенным правилам:

имя файла должно содержать не менее одного и не более восьми сим­

волов;

имя файла может иметь расширение, которое отделяется от имени точ­ кой и содержит не более трех символов;

для записи имен и расширений могут использоваться строчные и про­

писные буквы латинского алфавита a-z, A-Z, арабские цифры и некоторые специальные символы, например, символ подчеркивания «_» или знак дол­ лара «$»;

• в качестве имен запрещается использовать некоторые буквенные соче­ тания, которые зарезервированы операционной системой для обозначения устройств, например: PRN, CON, NUL, COMI, COM2, AUX, LPT1, LPT2, LPT3.

В операционных системах типа Windows некоторые из этих правил от­ меняются, например, имя файла может содержать больше восьми символов и включать символы русского алфавита. Однако при работе с файлами из Borland Pascal лучше придерживаться правил MS DOS.

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

188

6. Файловая система. Файлы

Существуют стандартные расширения, используемые операционной си­ стемой, например:

СОМ, ЕХЕ ~ исполняемые файлы (загрузочные файлы программ); PAS, BAS, СРР - файлы исходных текстов программ на алгоритмичес­

ких языках ПАСКАЛЬ, БЭЙСИК и C++ соответственно.

Для удобства работы с группами файлов применяют групповые имена файлов с использованием символов «*» и «?», где «*» соответствует любой последовательности символов, а «?» - одному любому символу, например:

*• ЕХЕ - все файлы с расширением ЕХЕ; А*. СОМ - все файлы типа СОМ с именами на букву «А»;

??В. PAS - все файлы типа PAS, имена которых содержат три символа, последний из которых «В»;

PRG1.* - файлы любых типов с именем PRG1; *.* - все файлы.

Для того чтобы MS DOS могла размещать файлы на дисках, последние должны быть специальным образом размечены (форматированы). Разметка осуществляется средствами используемой операционной системы. Если форматируется диск, бывший в употреблении, то вся хранившаяся на нем ин­ формация уничтожается и восстановлению не подлежит.

Как правило, диски хранят большое количество файлов (количество их на жестких дисках обычно исчисляется тысячами). Для удобства и ускорения работы с таким количеством файлов применяется древовидная структура ка­ талогов, аналогичная библиотечной.

Главным является корневой каталог, не имеющий имени и создаваемый в процессе форматизации диска системой. Файл корневого каталога состоит из записей, содержащих информацию о файлах, хранящихся на диске. В ка­ честве файлов главного каталога могут фигурировать пользовательские ка­ талоги, т.е. каталоги второго уровня (подкаталоги), каждый из которых мо­ жет содержать подкаталоги следующего уровня. Таким образом, получается дерево каталогов (рис. 6.1). Подкаталоги создаются и уничтожаются пользо­ вателем с помощью специальных команд. Все каталоги, кроме корневого, имеют имена, образованные по общим правилам операционной системы.

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

Перечисляемые в маршруте каталоги разделяются символом «\», причем перечень начинается с символа «\», так как корневой каталог не имеет име­ ни. Например:

189

Часть L Основы алгоритмизации и процедурное программирование

Рис. 6.1. Пример дерева каталогов

\katl\kat3\

Полное имя файла содержит также имя диска, на котором расположен файл. Например:

c:\katl\ kat3\file5.dat

Такая организация позволяет в разных подкаталогах создавать файлы с одинаковыми именами. Подкаталоги тоже могут иметь одинаковые имена, если они подчинены разным подкаталогам более высокого уровня.

6.2.Файлы Borland Pascal

ВBorland Pascal файл определяется как последовательность компонен­ тов, относящихся к одному типу: файл записей, файл целых чисел, файл строк и т. п. Особенностью файлов по сравнению с другими структурными типами данных является то, что в любой момент доступен только один ком­ понент. Количество компонентов файла заранее не определяется. Макси­ мальный размер файла, размещенного во внешней памяти, ограничивается лишь техническими возможностями вычислительной системы.

Различают дисковые файлы и логические устройства.

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

190