30 часов Бейсика для начинающих 1993 г.

Урок 9 - сортировка.


УРОК 9

9. 1 Введение.

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

в этой работе нан помогут подпрограммы и мы покажем чита-
телю, как их используют на БЕИСИКе для выполнения конкретных
часто встречающихся действий.

9. 2 Сортировка.

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

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

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

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

Сколько всего потребуется проходов? Очевидно, их число
равно количеству элементов списка минус 1, поскольку последний
проход для остатка списка, в котором только один элемент, можно
и не делать.

Поскольку каждый проход включает в себя серию повторяющих-
ся сравнений, то это очевидный кандидат на использование цикла

FOR. . . HEXT. Кроме того, нам нужен еше один цикл для того, в
котором будет меняться номер позиции, для которой сейчас ищется
Минин ал ьный элемент.

-FOR К=1 ТО П-1

i-for f = K*l ТО П

процедура обмена

L-HEXT f
-НЕХТ К

ВСК-9. 1

Используя рассмотренную методику, рассортируйте сле-
дующий список. Покажите, какие числа хранятся в

каждой позиции на каждой шагу.

Програнна, реализующая рассмотренный нам метод сортировки
данных выглядит так:

Програнна 9. 1

210 REM ««Процедура сортировки»«

220 FOR К=1 ТО П-1

230 FOR f- К*1 ТО П

240 IF X$(f)>=X$(K) THEN 00 ТО 275

250 LET t* X$-ff>

260 LET x*(f) = x* <K)

270 LET x*(K) - t$

275 REH ««Точка, в которую мы попадаем, если

пара данных уже расположена в должном
порядке»»

280 NEXT f
290 NEXT К

300 REH ««Конец процедуры сортировки»»
Использование процедуры сортировки.

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

Здесь: строки 50.. . 100 - ввод данных;

строки 210... 300 - выполнение сортировки;
строки 410. ..460
- печать отсортированного списка.

10 PRIHT "....... Процедура сортировки....."

11 PRIHT

15 REH ««Наксинальная длина слова - б симв. »»
30 DIH х»(20, 6)

50 LET К=1

55 REH ««ВВОД ДаННЫХ»»
60 INPUT "Очередное имя?";х*(К)
70 PRINT Х$(К)

80 IF X*(К)="ZZZZ " THEN GO ТО 185
90 LET К=К+1
100 GO ТО 55

180 REH «««в»»»»»»»»»*»»»»»»»»*»»»»»

185 REH »«Длина списка»»
190 LET П=К-1

200 REH »»»«»»»»»»«»»»»»«»»»»»««»««»

210 REH ««Процедура сортировки»*

220 FOR К=1 ТО 11-1

230 FOR f= К+1 ТОП

240 IF x*(f)>=X$(K) THEN GO TO 275

250 LET t* = X$(f)

260 LET X*(f) = X*(K>

270 LET X*(K) = t*

275 REH ««Точка, в которую мы попадаем, если

пара данных уже расположена в должном
порядке««

280 NEXT f
290 NEXT К

зоо REH ««конец процедуры сортировки»«

400 REM «»«»«»*««*»««»»»««»*»«»*»*»»*»««*»»»**»»>

410 PRINT

420 PRINT "Отсортированный список"

430 FOR р=1 ТО П

440 PRINT Х$(Р); " ";

450 NEXT P

460 PRINT

500 REM »*»»»»»»»»»«»»»»»»»»»«»»»*»*»»»»»»»»*»*»*i

9. 3 подпрограммы.

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

Давайте проиллюстрируем эту концепцию на примере нашей
программы для сортировки списка имен и начнем с Того, что
введем в нее еше две дополнительных отладочных печати списка.

1. Блок ввода - печать вводимого списка.

2. Блок сортировки - печать списка после каждого iaai

3. Блок вывода - печать итогового списка.

Поскольку здесь трижды производится печать чего-ли&„
мы можем офорнить блок печати отдельно и всякий раз, как
будет нужен, мы сможем его вызвать. Идея показана на рис.
35

Оператор go sub.

На "Спектруме" перейти к исполнению подпрограммы можно с
помошью оператора GO'
sub. за которым должен стоять номер стро-
ки. к
которой производится переход, каждая подпрограмма должна
заканчиваться оператором
return. этот оператор завершает испол-
нение подпрограммы и возвращает управление программой в опера-
тор, который стоит непосредственно за тем, из которого наша
подпрограмма вызывалась.

В нижеприведенном примере строка 30 передает управление
в
строку 200 и после исполнения строк 200 и 210 строка 220
возвращает управление в основное тело программы, в строку 40.
ю INPUT а
20 INPUT ь

30 GO SUB 200 --

-->40 LET s = a+b

50..............

200 PRINT "a","b" <--

210 PRINT a, b
--220 RETURN

Ibck-9. г

L.

Каково будет значение b в результате исполнения сле-
дующей программы, если ны введен в строке IHPUT:
а) число 5 Ь) число з ?

5 reh ««ВСК-9. г«»
ю ihput а

20 IF а<5 THEH GO ТО 35
30 GO SUB 75

35 REH ««Точка возврата»«
40 LET ь=а«а
50 PRIHT b
60 STOP

70 reh ««Подпрограмма»«
во
let a=i/a
90
return

а вот принер знаконой нам программы сортировки имен <
использованием подпрограмны печати списка.

10 PRIHT "....... Процедура сортировки....."

11 print

15 reh ««наксимальная длина слова - б симв. ««
30 dih x* (20, 6)
50 let к--1

55 rem ««ввод данных»«
60 ihput "Очередное иня?";х»(К)
70 priht х*(к)

80 IF X*(K>="ZZZZ " THEN GO TO 185
90 LET K--K + 1
100 GO TO 55

180 REM «««««««««««««««««««««x»»»»»
185 REM ««Длина списка»»

190 LET n=K-l

191 PAUSE 100

192 CLS

193 PRINT "ИСХОДНЫЙ СПИСОК"

194 PRINT "**«**««*««»**»*"

195 GO SUB 510

196 PRINT

200 REM «e»»»»»»»»*»»»»»»»»»»»»»»»»»

210 REM ««процедура сортировки»»
220 FOR K= 1 TO П-1
225 PRINT
"проход номер - ";к
227 PRINT "«ч»»»»»»»»»»»»»»»"

230 FOR f- KM TO П

240 IF X»(f)> X«(K) THEN GO TO 275

250 LET t$ X*(f>

260 LET X*(f) = X*(K)
270 LET X»(K) = t*

275 КЕМ ««Точка, в которую мы попадаем, если

пара данных уже расположена в должном
порядке««
280 GO SUB 510
285 НЕХТ f
287 PRIHT
290 НЕХТ К

300 REH ««Конец процедуры сортировки»»

400 REH «««*«*««««««*«««*«««*««««»«««««««««*«««

410 PRIHT

420 PRIHT "Отсортированный список"

425 PRIHT "«а»»»»»»»..............

430 GO SUB 510
450 STOP

500 REH ««Процедура печати*»

510 FOR ТОП

520 PRIHT x$(p)i" ";

530 HEXT P

540 PRIHT

550 RETURH

RUH

Исходный список

»»h*h*kk*«h«kttk

Тони Сэм Пит Джо билл

Проход номер - 1

кк»хикк«кии«»»к»

Сэн Тони Пит ДЖО БИЛЛ

Пит Тони Сэм Джо Билл

Джо тони сэн Пит Билл

Билл тони Сэм пш джо

Проход номер - 2

«кя«и*к««»и«н«ик

Билл сэн Тони Пит джо

Билл Пит Тони Сэн джо

Билл Джо Тони Сэм Пит

Проход номер - 3

»м*»к»ккм»»кк»мк

Билл Джо Сэн Тони Пит

Билл Джо Пит Тони Сэм

Проход номер - 4
шшошхш

билл джо пит сэм тони

Отсортированный список

■ «••«кмкк к к мкмкмнжнкмкм

билл джо пит сэм тони

Примеры подпрограмм.

основное назначение подпрограмм состоит в упрощении и со-
кращении сложных и длинных программ. Поэтону
это достаточно
противоречивая задача - показать на
коротких и понятных приме-
рах возможность эффективного применения подпрограмм. НЫ вос-
пользуемся тем случаем, когда одни и те же или похожие действия
выполняются неоднократно в разных местах одной программы.

Рассмотрим игру в кости. Дважды бросается пара
костей и если очки в первом и во
втором бросках
пары равны, то игра заканчивается. Если они различаются, игра
продолжается. Напишите
прогрзнму, которая промоделирует броса-
ние костей и распечатает количество бросков, потребовавшихся
для получения равных результатов.

ПРИМЕР-9. 1

5 REH ««Имитатор игры в кости»»

Ю PRIHT ".............2 одинаковых броска

15 PRIHT
30 LET С=1

35 REH »»1-ЫЙ 6РОСОК»»
40 GO SUB 120
50 LET
si = s
55 REH »»2-ОЙ 6POCOK»»
60 GO SUB 120
70 LET 32 = S

80 IF Si = S2 THEH GO TO 100
90 LET
c=c+1
95 GO TO 35

100 REH ««Печать результата»»

105 PRIHT "Результат ";sli" в ";c;" бросках"

110 STOP

120 REH ««Подпрограмма бросания костей»»

130 LET dl = IHT(6«RHD ♦ 1)

140 LET d2 = IHT(6«RHD ♦ 1)

150 LET s=dl + d2

160 RETURN

УПРАЖНЕНИЕ-9. 1

а) Напишите фрагмент программы, который распе-
чатает
строку из 32-х символов "-".

b) Напишите фрагмент, который распечатает "подводную лодку" на
экране в позиции, заданной переменной з. для изображения
"подводной лодки" воспользуйтесь
стрингон "<->"

c) Напишите программу, которая распечатает строку символов "-",
затеи в следующей строке нарисует "подводную лодку" в пози-
ции, заданной переменной s и. распечатает еше одну
строку из

32-х символов "-". Печать строки "-------" исполните в виде

подпрограммы.

Если Вы выполнили предыдущее упражнение, то
должны заметить, что наша посудина скорее на-
поминает судно в канале, чем подводную лодку в море, но все-
таки это какая-никакая, а заготовка для возможной игры. Напи-
шите программу, которая сгенерирует случайное число от 1 до зо
и напечатает "подводную
лодку" в канале с этими координатами.

УПРАЖНЕНИЕ-9. 2

а теперь сыграем в игру. Компьютер генерирует
некоторое случайное число. Ваша задача - най-
ти "
подводную лодку", т.е. отгадать это число (от 1 до 32).
Если Ваше число попадает в диапазон от s до s+2 (лодка имеет в
длину
три символа), то компьютер пишет " !!! " и игра заканчи-
вается. Если же Вы не попали, то компьютер пишет "???" и дает
Вам очередную попытку. Напишите программу, которая исполнит

эту игру.

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

9. 4 Поиск.

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

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

УПРАЖНЕНИЕ-9. 3

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

Метод половинного деления.

термин "открываем "на глаз"" - не очень конкретен для
того, чтобы его ножно было использовать в вычислительном
алгоритме. Здесь нужен другой подход, например:

- делим весь набор элементов пополам и определяем, в какой
половине находится нужный нам элемент;

- если он в нижней половине, то теперь мы считаем, что эта
нижняя половина теперь и есть весь набор элементов;

- то же самое, если он - в верхней половине;

- и в том и в другом случае мы отбрасываем ненужную поло-
вину. а с оставшейся продолжаем поступать точно таким же обра-
зом.

Упорядоченный список содержит элементы:
A, F. I. М. Р. Т. и. Z.
методом половинного деления мы должны определить, содержится ли
элемент "Р" в этом списке.

Назовем "Р" словом - "Запрос". Это элемент, которым мы
интересуемся.

ПРИМЕР 9. 2

индекс
Элемент
Исходный эл-т
Средний эл-т

1 2
A F
(1)

4

н

(4)

5
Р

б
Т

7
U

Проверяем: "Запрос" = элементу (4)? - НЕТ
"Запрос" < элемента (4)? - НЕТ
Формируем новый список:

Индекс
Элемент
Исходный эл-т
Средний эл-т

4 5

н Р

(4)

б
Т

(6)

7
О

проверяем: "Запрос" = элементу (б)? - НЕТ
"Запрос" < элемента (б)? -
да
Формируем новый список:

Индекс 4

элемент н

Исходный эл-т (4)
Средний эл-т

Проверяем: "Запрос"

5 б
Р Т

(5)

= элементу (5)? - ДА

УПРАШЕНИЕ-9. 4

Проведите по тому же списку данных поиск эле-
мента "I".

Ны увидели, что для поиска по списку из в элементов нан
потребовалось всего лишь
три шага. Тен не ненее, это небольшое
преимущество перед обычным поэлементным перебором всего списка.
По-настояшену эффективность этого нетода проявляется на больших
и очень больших списках, ны это проденонстрируен, но пока нан
надо увязать кое-какие неувязки.

Проблены поиска. Где остановиться?

Вернемся опять к нашему ПРИМЕРУ-9. 2. Что будет, если мы
начнем искать в нашей списке эленент "Q"? Этого эленента в спи-
ске нет и, если Вы попробуете его отыскать, то быстро обнаружи-
те, что поиск "зацикливается", т. е. он не ножет остановиться,
поскольку никакого естественного выхода из алгоритна в нашем
случае не имеется. Компьютер будет без конца пытаться отыскать
этот элемент между элементани "Р" и "Т".

Здесь уже и содержится ответ на нашу проблену. Когда
список "съеживается" до размера
двух соседних элементов, а
нужный на так и не найден, то продолжать его бесполезно. Таким
образон, поиск заканчивается когда либо элемент найден, либо
когда младший и старший элемент инеют индексы, отличающиеся
только на единицу (стоят рядом).

Проблемы поиска. С чего начать?

Вроде бы с этим нет никаких проблем. Принимаем первый
элемент за младший, а последний - за старший и ишем середину.
Все это хорошо, если наш список генеральный, т. е. в него
входят все возможные элементы, а если это не так? Рассмотрим
конкретный пример.
Пусть у нас есть список элементов от С до S.
1 2 3 '1 5

СКОР S

И что же будет, если "запрос" равен "А" или "В" или нахо
лится выше "S"? Наш процесс вообше не сможет работать. Самый
простой способ решения этой проблемы принудительно генерали
зовать список, т.е. включить в него в качестве наимладшего -эле-
мента "заглушку"
аааа. а в качестве наистаршего элемента за-
глушку "zzzz".

Блок-схема алгоритма.

Теперь нам осталось только написать образец программы
поиска.

Ю КЕН ««Поиск методом половинного деления»«
20 DIM
п$ (20, &)
JO DIM t$<20, 4)
'10 LET К= 1

15 кем ««ввод данных»*

50 READ П*(К)
55 READ
t*(K>

60 IF П»(К,1)= "«* THEN GO TO 90
70 LET К = К + 1
80 GO TO 15

90 REH «и»»»»»»»**»»»»»*»»»**»»»

100 LET n=K

105 REH «»Мы нашли конец списка»»

110 REH о»»»»»»»»»»»»»»»»»»»»»»»

150 INPUT "ЗаПРОС?"; Ч*

гоо REH »«начало поиска»»

210 PRINT " m";TAB 5;" s"; TAB 10;" d";

TAB 15; "П* (d) "
220 LET rn=1
225 LET
S = ll

230 REH »»»««»»««««»»«»«»»««»»»««

235 IF S-m=1 THEN GO TO 500
240 LET d=INT((S+m)/2)

250 PRINT m; TAB 5; s; TAB 10; d; TAB I5;n$(d)

260 IF q* = n*(d> THEN GO TO 320

270 IF <t»<n*(d) THEN GO TO 300

280 LET id=d

290 GO TO 230

300 LET S=d

310 GO TO 230

320 reh ««конец поиска»»

330 PRINT ч»;" - тел. номер - ";t*<d)

350 GO TO 600

500 REH »«Таких данных нет»»

510 PRINT q»; " в списке нет"

600 REH ««Продолжаем или нет?»»

605 INPUT "Вы желаете искать другое имя?";г$

610 IF Г* "у" THEN GO ТО 110

890 REH ««Список данных»»

900 DATA "аааааа","0000"

910 DATA "Barrow","1234"

920 DATA "COPPer". "9832"

930 DATA "Draper". "1980"

940 DATA "Edward". "7894"

950 ....................

999 DATA "«End","9999"
1000 STOP

9. 5 Таблицы.

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

13 - 6613

ножей создавать списки (см. урок 4). которые в то же время
являются одномерными массивами,
другой метод хранения большого
количества данных - организация их в таблицы или в двумерные
массивы.

Предположим, Вам надо хранить следующие данные:

Доходы станции обслуживания автомобилей.

1-ый кв-л

2-ой кв-л

з-ий кв-л

4-ый кв-л

Продажа з/ч

20

70

80

40

Обслуживание

10

14

18

11

ГСН

30

45

50

30

Эти данные можно было бы разместить в одном списке, но в
этом случае их
трудно использовать. Придется все время помнить,
что первые четыре числа относятся к доходам от продажи запчас
тей. следующие четыре числа - к доходам за обслуживание и т. д.
К счастью. БЕИСИК "Спектрума" позволяет нам создавать так назы-
ваемые двумерные массивы и присваивать им имена, состоящие из
одной буквы латинского алфавита, т. е. мы можем иметь в програм-
мах до 26-ти разных двумерных массивов.

Сравнение списков и таблиц.

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

список: All), А<г>, А (3). . А (К)

^--------индекс, указывающий на то, что

этот элемент списка имеет по-
рядковый номер 3.

Таблица: А < 1. 1) All.2) All. 3). . .

А 12. 1) А(г.2) А 12. 3). . .

А ( 3. 1) А I 3, 2) AI3. 3). . .

^------------------- индекс, указывающий на то, что

этот элемент таблицы находится
в третьем ряду, во втором
столбце.

Таблицы (двумерные массивы) могут содержать только либо
числовую, либо символьную информацию. Смешивать числа и стрин-
ги нельзя, конечно Ван не запрещено хранить числа в Форме
стрингов. а потом конвертировать их назад с помошью функции
VAL.

Таблицу наших данных по доходам станции техобслуживания мы
можем представить в виде двумерного массива:
t(t.l) t (1. 2) t(l.3) t(1.4)
t (2. 1) t (2. 2) t (2. 3) t (2. 4)
t(3.1) t (3, 2) t(3.3) t (3. 4}

Тогда t(l.l) = 20; t (2. 1) = 10; t(3. 3) = 50 и т. д.

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

ПРИМЕР-9. 3

13s

Поле 1

Поле 2

Имя

Номер телефона

запись 1
Запись 2
Запись з
Запись 4

Benny
Copper
Draper
Eddie

1234
9823
1850
7294

В более обшей Форме эту таблицу можно представить так:

Поле 1

Поле 2

поле з

и т. д.

Запись 1
Запись 2
Запись 3
и т. д.

31П1
32П1
ЗЗП1

31П2
32 П 2
ЗЗП2

31 пз

Э2ПЗ
ЗЗПЗ

Ниже приведена таблица п*. содержащая 9 единиц
данных. Каковы имена переменных для этих данных?

1

2

3

1

Benny

Copper

Draper

2

Eddie

Gwynne

Hetty

3

Мог ley

Prosser

Smylhe

Berrny = n$ (1, 1)
Eddie = n*<2.1)
Ног ley = n$<3, l)

Решение

Copper = n*(1.2)
Gwynne = n$ (2.2)
Prosser=n*(3. 2)

Draper = n$(1.3)
Hetty = n* (2.3)
Smythe= n*(3.3)

В нижеследующей таблиде а» определите имена перемен-
ных аналогично
тому, как это было сделано в вышепри-

BCK-9. 3

веденном примере.

Copper

Frame

Kemp

HoaKes

Talt

Archer

Draper

Gwynne

Lamb

Prosser

Benny
Eddie
Hetty
Могley
Smythe

Оператор DIH для двумерных массивов.

Если Вам нужен двумерный ЧИСЛОВОЙ массив, то Вы предвари-
тельно должны оповестить компьютер о размерах этого нассива.
что и делается с помошью оператора DIH. например:
DIM а(3.4)

[----------- количество столбцов в массиве

- количество строк

это надо сделать до того, как Вы в первый раз воспользуе-
тесь этим нассивон или любын его эленентон.

То же самое относится и к двумернын СТРИНГОВЫМ массивам,
но здесь необходимо также определиться с наксинальной длиной
входящего в этот нассив стринга. поэтону оператор DIH здесь
имеет следующий вид:

DIM at (3, 4. 8)

^------- наксинальная длина стрнга

- количество столбцов

- количество строк

Двумерные массивы и вложенные циклы.

Ны говорили, что кажется, будто одномерные массивы и циклы
FOR. . . НЕХТ созданы друг для друга. Это в еше большей степени
относится к двумерным массивам и вложенным циклам FOR. . . НЕХТ.

Предположим, Ван надо считать список имен: Archer, Benny,
Copper, Draper, Eddie, Frame, Gwynne, Hetty, Kemp, Lamb,
Morley, NoaKes. Prosser. Smythe. Talt, WeeKs в двумерный массив
имен п*. состоящий из 4-х Рядов и 4-х столбцов. Это легко ис-
полняется с помошью ввода через INPUT, находящегося внутри двух

вложенных циклов.

60 FOR К=1 ТО 4
70 FOR J = 1 ТО 4
80 INPUT "Введите имя"; n$(K, j)

82 PRINT П*(К. j)

83 PRINT TAB 30;4»(К-1)♦j
90 NEXT J

100 NEXT К

Это только фрагмент другой, более крупной программы, поэ-
тому здесь нет оператора DIH, саму же программу вы увидите ни-
же (программа 9. 1)

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

Програмна 9. 1

5 rem ««массив 4 х 4«»
10 PRINT "Ввод и вывод табличных данных"
15 PRINT

20 PRINT "Ввод 16 ти имен"

30 DIM П$ (20. 5. 7)

40 REM ««процедура ввода»»

60 FOR К=1 ТО 4

70 FOR j=l ТО 4

80 INPUT "Введите имя";п*(К. j)

82 PRINT П»(К. J )

83 PRINT TAB 30;4»(K-l)+J
90 NEXT j

100 NEXT К

110 REM ««процедура вывода««

111 PR1 NT

11? PRINT "Таблица заполнена"
113 PAUSE 100
1 1 5 CI.S

130 FOR к 1 TO 4
140
FOR j = 1 TO 4

150 PRINT K; TAB 10;j;TAB 20;n$(K,J)
160 NEXT j
170 NEXT К
^00 STOP

IBCK 9.4 В программу 9. 1 были внесены следующие изменения:
L— (Ю FOR К: 1 ТО 3

YO FOR J I ТО 5
1 30 FOR К 1 ТО 3
140 FOR j 1 ТО 5

Напишите, как теперь будет выглядеть печать результатов
работы этой программы?

Табличный вывод.

Результаты работы программы 9. 1 следует все же признать
неудовлетворительными. Раз уж мы выводим на печать табличные
данные, то хотелось бы, чтобы они и были оформлены в виде
таблицы. Это можно сделать, если выполнять печать с помошыэ не
Фиксированного оператора TAB, а сделать его вычисляемым, в
зависимости от номера печатаемого элемента (см. программу 9. 2)

Программа 9. 2

5 rem ««Массив 5 x 3««
ю prist
"Ввод и вывод табличных данных"
15 print

20 print "Ввод 15-ти имен"
30 dim п* (20, 5, 7)
40 rem ««процедура ввода»»
60
for К=1 то 5
70 for J=1 то 3

80 INPUT "Введите имя";п*(К.J)

82 PRINT П*(К,J)

83 PRINT TAB 30;3«(K-1)+J
90 NEXT j

100 NEXT К

110 REM ««процедура вывода»»

111 PRINT

112 PRINT "Таблица заполнена"

113 PAUSE 100
115 CLS

130 FOR K=1 TO 5
140 FOR J=1 TO 3

150 PRINT TAB (10«(J-l));n$(K, J);

160 NEXT j

170 PRINT

180 NEXT К

200 STOP

9. 5 Многооператорные строки.

"Спектрум" позволяет использовать сразу несколько
операторов в одной программной строке. Для этого операторы
должны отделяться друг от друга с помошью двоеточия.

Так, запись

Ю FOR я -1 то 10: PRINT "Номер строки х: NEXT а
выглядит безусловно короче, чем:

10 for х=1 to 10

го print "Номер строки ";х

30 NEXT X

но запись в одну строку ничуть не повышает эффективность
работы программы, хотя
чуть-чуть уменьшает объен расходуемой
оперативной памяти. С другой
стороны, ухудшается удобочитае-
мость программы и. если
строки становятся слишком длинными, на-
много замедляется работа редактора строк.
Поэтону, учитывая,
что эта книга предназначена для начинающих программистов (а они
никогда не испытывают проблем с нехваткой памяти). на страницах
этой книги до сих пор не применяли многооператорных строк.

Тем не менее, мы рекомендуем применение многооператорных
строк по крайней мере в том случае, когда Вам надо вставить в
строку оператор REH для того, чтобы пояснить, что в этой строке

делается, например:

гю LET n=n-l: REH корректируем счетчик, поскольку zzzz не
является входной информацией.

9. 7 Меню.

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

СДЕЛАЙТЕ ВЫБОР

1. Что такое скорость?

2. Что такое энергия?

3. Что такое работа?

4. Еденицы измерения энергии.

Рис. 37

В строках 390. . . 450 определяется и проверяется клавиша,
которую нажал пользователь. Если проверка не проходит, т. е.
пользователь нажал не
ту клавишу, то програнма продолжает
терпеливо ожидать нажатия
цифровой клавиши 1...4. О том. как
делается такая проверка, мы
говорили в уроке 5. В этом примере
если пользователь нажмет клавишу "О", то экран очистится и
потом снова появится то же меню. Это сделано для того, чтобы
пользователь знал, что программа не "зависла", а ждет нажатия
правильной клавиши. В строках 510. . . 570 обрабатывается тот
случай, когда пользователь нахал на клавишу больше 4. В этой
случае на короткое время выбрасывается сообщение, после чего
экран очишается и неню печатается вновь.

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

Настоящая же ценность этого фрагмента заключена в строках
590 и 600. когда установлено, что пользователь нажал правильную
клавишу, здесь выполняется переход к
нужному фрагменту програм-
мы. Это сделано с поношью вычисляемого оператора перехода
GO ТО:

600 go то ч* 1000

Так. если пользователь нажал клавишу 1. то переход будет
сделан к строке

1«1000 - юоо

и. соответствен©:

2. г»юоо - к строке 2000

3. з* юоо - к строке зооо

4. 4*1ооо - к строке 4000

Конечно, если бы ны здесь распечатали всю программу
целиком, то в строках юоо. . . 1999 вы увидели бы фрагмент, в
котором рассказывается, что такое скорость с примерами и
задачами, в строках 2000...2999 - то же самое про энергию и
т. д. Но, поскольку мы ограничены объемом книги, мы в этих
строках поставили временную "заглушку" - сообщение.

300 REM ««Демонстрация мегао««
310 CLS

320 priht at 4,8; "сделайте выбор"
330 print at
5, 0; "_ __ _ . "

340 print at 8,3; "1. Что такое скорость?"
350 print at 9,3; "2. Что такое энергия?"
360
print at 10, i; "3. Что такое работа?"
370
print at 11,3; "4. Единицы измерения энергии. "
380
print at 18,0; "Выберите нужный пункт и нажмите
enter"

390 REH ««Проверка ввода»»
400 INPUT q$

410 IK q$ "" THEN GO TO 390
420 FOR Z =1 TO LEN(q$)

430 IF 4* (2) < "0" OR q$(Z)>9 THEN CO TO 390

450 LET 4=VAL 4$

460 IF q>0 THEN GO TO 510

470 REM ««Повторить меню««

480 CI.S

490 PAUSE 50
500 GO TO 300

510 REM »«Проверка избранного пункта»»

520 IF q<5 THEH GO TO 580

530 REM ««Недействующий пункт»»

540 PRINT AT 18.0; "Только ЦИФРУ ОТ 1 ДО 4,

пожалуйста!"
550 PAUSE 150
560 CLS
570 GO TO 300

580 REM ««Действующий пункт»«

590 CLS

600 GO TO q«1000

1000 REM ««Раздел, посвященный скорости»»
1010 CLS

1020 PRINT "Здесь Вы разместите свою информацию"
1030 PAUSE 100
1040 GO ТО 300

2000 REM ««Раздел, посвященный энергии»

2010 CLS

2020 PRINT "Здесь Вы разместите свою информацию"
2030 PAUSE 100
2040 GO ТО 300

зооо REM ««Раздел, посвяшенный работе»»

ЗОЮ CLS

3020 PRINT "Здесь Вы разместите свою информацию"
3030 PAUSE 100
3040 GO ТО 300

4000 REM ««Раздел, посвяшенный единицам измерения»«

4010 CLS

4020 PRINT "Здесь Вы разместите свою информацию"
4030 PAUSE 100
4040 GO ТО 300

УПРАХНЕНИЕ 9. 5

Программа, демонстрирующая систему организа-
ции программного неню, не имеет естественно-
го Финала и нам придется прерывать ее с помошью клавиши BREAK.
Подумайте и сделайте
так, чтобы в меню был еше и пятый пункт
"Конец работы", завершающий программу естественным путем.

ОБЗОР УРОКА

Закончив этот последний урок, проверьте свои знания по
следующему списку:

сортировка набора данных;

использование вложенных циклов для сортировки данных;

- вызов подпрограмм с помошью GO SUB;

- поиск данных методом половинного деления;

- размещение данных в двумерном массиве;

- ввод данных в двумерный массив;
печать данных из двумерного массива;

- организация программного меню.

ОТВЕТЫ НА ВОПРОСЫ ДЛЯ САМОКОНТРОЛЯ

0 6

4

1

2

3

7

8

0 1

6

4

2

7

8

0 I

2

6

4

3

7

8

0 1

2

3

6

4

7

8

0 1

2

3

4

6

7

8

0 1

2

3

4

6

7

8

0 1

2

3

4

6

7

8

а)

Ъ 1/25

Ь> Ъ=9

BCK

-9. 2

BCK

-9. з)
__J

1----

а* (1. 2)-Benny
а*(2.2)=Eddie
а$ (3. 2) = Hetty
а»(4,2)-Мог ley
а$ <5,2)=Smythe

а$(1,1> Archer
а$(2. 1)- Draper
а» (3.1)
Gwynne
а* <4, 1) - Lamb
at(5, 1) -Prosser

а*(1,3) Copper
а* (2. 3) =Framer
а» (3, 3) =Кешр
а»(4. 3)-Hoaxes
а»
(5. 3) -Talt

ВСК-9. 4

SUN

к j n$(k, j)

1 1 Archer

1 2 Benny

1 з copper

1 4 Draper

1 5 Eddie
2. 1 Frame

2 2 Gwynne
2 3 Hetty
2 4 Kemp

2 5 Lamb

3 i мог 1ey
3 2 NoaKes
3 3 Prosser
3 4 Sidy the
3 5 Tait

ОТВЕТЫ К УПРАХНЕНИЯМ

a) 5 rem «« Упражнение la »«
10 for к=1 то 32

20 PRINT
30 НЕХТ К
40 PRINT

b) 30 PRINT TAB s; "< = >"

с) 10 for k=1 to 32

15 input s

16 PRINT s

20 GO SUB 100
30 PRINT TAB s; "< = >"
40 GO SUB 100
50 STOP

loo reh ««канал»*
110 for k=1 to 32
120 print
130 next к
140 print
150 return

УПРАХНЕНИЕ~9. 2

10 reh ««Подводная лодка»»
50 let s- int(29«rnd+1)
60
GO sub 510
70 print tab
s; "< = >"
80 GO sub 510
90 stop

500 reh ««Процедура печати»«

510 for к 1 to 32

520 print

530 next к

540 print

550 return

упрахнение-9. 1

10 rem ««Подводная лодка««
30 rem ««Печать канала««
40 GO SUB 300

50 print "Угадите, где я: Число от 1 до 29"
60
GO SUB 30

70 rem ««Случайная позиция лодки»«
80 LET s- int(rnd«29+1)
85 rem
««Следующий ход««
90 print

УПРАЖНЕНИЕ-9. 3

юо INPUT "Попробуйте другое число";х

110 IF X<S THEN GO TO 190

120 IF X>S + 2 THEN GO TO 190

130 REH ««Есть попадание»»

140 GO SUB 300

150 PRINT TAB s; "!!!"

160 GO SUB 300

170 GO TO 320

180 REH »«Промах»»

190 GO SUB 300

200 PRIHT "???"

210 GO SUB 300

220 INPUT "Сыграем еше?";г»

225 PRINT Г*

230 IF г$="У" OR ri--"Y" THEN GO TO 85

240 PRINT "Назила! А я была здесь!"

245 PRINT

250 GO SUB 300

260 PRINT TAB s;"<=>"

270 GO SUB 300

280 GO TO 320

290 REH ««Печать»«

300 FOR K=1 TO 32

305 PRINT "-";

310 NEXT К

311 PRINT
315 RETURN
320 STOP

УПРАХНЕНИЕ-9. 4

Индекс
Элемент
Исходный эл-т
Средний эл-т

проверяем: "Запрос"

"Запрос" <
Формируем новый список:

Индекс 1

Элемент Л

Исходный эл т (1)
Средний эл-т

з 4 5 ь

I Н I' 'I'

(4)

элементу (4)? НЕТ
элемента
(4)? - да

2 3 4
F 1 Н

(2)

1 2
A F
(1)

Проверяем: "Запрос" элементу (2)?

"Запрос" • элемента (2)?

НЕТ
НЕТ

Форнируем новый список:

Индекс 2 3 4

Элемент F I И

Исходный эл-т (2) :

Средний эл-т (3)

Проверяен: "Запрос" = элененту (3)? - ДА

Цупрахнение-9. 5Ц Вам надо добавить к програнме следуюоше стро-
ки и
некотрые строки изненить:

375 PRIHT AT 12,3; "5. Конец работы."
520 IF q<6 THEN GO TO 580

540 PRINT AT 18,0; "только цифру от 1 до 5,
пожалуйста!"
5000 REH ««Окончание работы»«
5010 CLS

5020 PRINT "Вы уверены в тон, что хотите

закончить рабоут? Y/N?"
5030
input у*

5040 IF у* = "у" OR у$ -- "V" THEN GO ТО 5060

5050 GO ТО 300
5060 STOP




  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Во что играем? - обзор спектрумовских игр недели.
Железо - Возможность подключения компьютера ZX spectrum к TV через Scart.
Реклама - двигатель торговли.
Улыбнемся - За трезвый образ жизни.
Система - обзор прикладных программ.

В этот день...   24 апреля