УРОК 9
9. 1 Введение.
в этом уроке мы еше раз поговорим о том, насколько важной
бывает в программах сортировка данных. в частности, мы обсудим
один широко применяемый метод сортировки, а также покажем, как
можно организовывать поиск по отсортированным данным.
в этой работе нан помогут подпрограммы и мы покажем чита-
телю, как их используют на БЕИСИКе для выполнения конкретных
часто встречающихся действий.
9. 2 Сортировка.
в четвертом уроке мы уже обсуждали вопрос о том, как отыс-
кать член списка, имеющий минимальное значение. Мы делали это с
помошью процедуры обмена,, которая ставила текущий минимальный
элемент первым в списке. Там же.мы сказали, что такую же проце-
дуру можно повторить и для оставшейсй части списка, выбрав из
нее минимальный элемент и поставив его на вторую позицию и т. д.
поскольку процедуры сортировки имеют очень важное значение в
программировании, сейчас мы рассмотрим эту технику поподробнее.
Первый проход. В этом проходе все элементы списка сравни-
ваются с первым элементом и, если находится элемент меньший,
чем первый, то они меняются местами, после чего просмотр списка
продолжается. Таким образом, текущий минимальный элемент всегда
находится в первой позиции.
Второй проход. Теперь мы можем проигнорировать первую
позицию и повторить тот же самый процесс, начиная со второй
позиции списка и до конца. В результате минимальный элемент
оставшейся части списка окажется в позиции г.
Третий проход. Теперь мы можем проигнорировать первые две
позиции списка, поскольку они уже содержат два минимальных эле-
мента. процесс повторяется для укороченного списка с третьей
позиции и до конца, так мы находим очередное минимальное число
и, в результате, оно занимает третью позицию. и так далее.
Сколько всего потребуется проходов? Очевидно, их число
равно количеству элементов списка минус 1, поскольку последний
проход для остатка списка, в котором только один элемент, можно
и не делать.
Поскольку каждый проход включает в себя серию повторяющих-
ся сравнений, то это очевидный кандидат на использование цикла
FOR. . . HEXT. Кроме того, нам нужен еше один цикл для того, в
котором будет меняться номер позиции, для которой сейчас ищется
Минин ал ьный элемент.
-FOR К=1 ТО П-1
i-for f = K*l ТО П
процедура обмена
L-HEXT f
-НЕХТ К
Используя рассмотренную методику, рассортируйте сле-
дующий список. Покажите, какие числа хранятся в
каждой позиции на каждой шагу.
Програнна, реализующая рассмотренный нам метод сортировки
данных выглядит так:
Програнна 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
а) Напишите фрагмент программы, который распе-
чатает строку из 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)? - НЕТ
Формируем новый список:
Индекс
Элемент
Исходный эл-т
Средний эл-т
проверяем: "Запрос" = элементу (б)? - НЕТ
"Запрос" < элемента (б)? - да
Формируем новый список:
Индекс 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 и т. д.
Если мы подумаем, то вспомним, что с табличной Формы
представления данных мы уже встречались на страницах этой
книги, когда говорили о файлах базы данных. Вспомним наш
телефонный справочник:
|
Поле 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)
В нижеследующей таблиде а» определите имена перемен-
ных аналогично тому, как это было сделано в вышепри-
веденном примере.
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
к 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
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
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
юо 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)
Проверяем: "Запрос" элементу (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