Главная » Просмотр файлов » Н. Вирт - Программирование на языке Модула-2

Н. Вирт - Программирование на языке Модула-2 (1160777), страница 9

Файл №1160777 Н. Вирт - Программирование на языке Модула-2 (Н. Вирт - Программирование на языке Модула-2) 9 страницаН. Вирт - Программирование на языке Модула-2 (1160777) страница 92019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 9)

приусловии, что а[i-1] <= a[i] для всех i = 1... N-l. Лучший метод - это так называемый двоичныйпоиск: проверить средний элемент массива, а затем применить этот же метод к левой или правой37половине. Этот алгоритм реализует следующий далее фрагмент программы (предполагается, что N> 0). Инвариантами цикла являются условия (а[к] < х для всех к = 0...i-1) и (а[к] > х для всех к j+1...N-1)1 := 0; j := N-1; найден := FALSE;REPEAT центр := (i + j) DIV 2;IF x < а[центр] THEN j := центр - 1ELSIF x > а[центр] THEN i := центр + 1ELSE найден := TRUEENDUNTIL (i > j) OR найденПоскольку каждый шаг делит интервал поиска пополам, то число необходимых сравненийравно всего лишь los2(N). Приведем другую, более эффективную версию, исключающуюсоставное условие завершения.i := 0; j := N-1;REPEAT центр := (1 + J) DIV 2:IF x <+ а[центр] THEN j := центр - 1 END;IF x >= а[центр] THEN i := центр + 1 ENDUNTIL i > j; IF i > j+1 THEN найден ELSE не найден ENDНиже приведена еще более изощренная версия.

Ее основная идея - не прекращать поисксразу, как только элемент найден, поскольку это довольно редкое событие по сравнению с числомбезуспешных проверок.1 : = 0; j := N-1;REPEAT центр := (i + j) DIV 2;IF x < а[центр] THEN j := центрELSE i := центр + 1ENDUNTIL i >= jНа этом завершим список примеров использования простых массивов. Все элементымассива имеют одинаковый тип, однако сам элемент может быть в свою очередь массивом(фактически, как мы увидим далее, это может быть любой структурированный тип). Массивмассивов называется многомерным массивом или матрицей, поскольку можно, считать, чтокаждый индекс соответствует одному измерению в декартовом пространстве. Вот примерыдвумерных массивов:a: ARRAY [l.

.N], [t. .N] OF REALT: ARRAY [0. .M-1], [0. .N-1] OF CHARпредставляющие собой сокращение следующих полных Форм:a: ARRAY [1..N] OF38ARRAY [1..N] OFREALT: ARRAY [0..М-1] OFARRAY [0. .N-1] OFCHARОтступы используются, чтобы отразить иерархическую структуру описания. Общийсинтаксис типа массив таков:$ ТипМассив = "ARRAY" ПростойТип {"," ПростойТип}$"OF" Тип.Здесь простой тип, обозначающий диапазон индексов, имеет либо вид"[" КонстВыражение ".." КонстВыражение "]"либо является идентификатором. Например, описание массиваmap: ARRAY[" ".."~"] OF CARDINALвводит массив из 95 чисел типа CARDINAL, причем каждый элемент индексируетсяграфической литерой, как это показано в следующих операторах:map["А"] := 0; k := map["+"]Синтаксис обозначений допускает сокращение, аналогичное сокращениям в описаниях:можно писать a[i,j] вместо a[i][j].

Однако последняя Форма отчетливее выражает тот Факт, что [J]является индексом массива а[i]. Синтаксис обозначения элемента массива:$ Обозначение - КвалИдент {"[" СписВыражений "]"}.$ СписВыражений - Выражение {"," Выражение}.При работе с матрицами оператор цикла с шагом демонстрирует все свои преимущества,особенно в числовых применениях. Канонический пример - перемножение двух матриц, гдекаждый элемент произведения с - а*Ь определяется какc[i,j] = a[i,1]*b[l,j] + a[i,2]*b[2,j] + ......

+ a[i,N]*b[N,j]Пусть имеются описанияa: ARRAY [1..М], [1..К] OF REAL:b: ARRAY [1..K],[1..N] OF REAL:с: ARRAY [1..Ml,I1..N] OF REALАлгоритм умножения состоит из трех вложенных друг в друга цикловFOR i := 1 ТО М DOFOR j := 1 ТО N DOсумма := 0.0;39FOR k := 1 ТО К DOсумма := a[i,k]*b[k,j] + суммаEND;c[i,j] := суммаENDENDВо втором примере мы демонстрируем поиск слова в таблице. Каждое слово в таблице массив литер.

Предполагаем, что таблица Т описана так же, как в одном из приведенных вышепримеров, а х задан следующим образом:х: ARRAY [0..N-1] OF CHARНаше решение использует типичный линейный поиск:i := 0; найден := FALSE; WHILE ~найден&(1 < М) DOнайден := "Т[i] равен х"ji := i + 1ENDЕсли определить равенство двух слов х и у как x[j] = у[i] для всех j = 0...N-1, то можновыразить "внутренний" поиск в таком виде:j := 0; равно := TRUE;WHILE равно&(j < N) DOравно := T[i,j] = x[j]; j := j + 1END;найден := равноЭто решение выглядит довольно неуклюжим, однако в случае М > 0 и N > 0 его можнопреобразовать в более простую Форму. Окончательный вариант алгоритма поиска в таблицеможно записать так:i := 0:REPEAT j := 0;REPEAT В := T[i,j] # x[j]; j := j + 1UNTIL В OR (j = N);i := i+lUNTIL NOT В OR (i = M)Значение логической переменной В в конца фрагмента имеет следующий смысл: "слово хне найдено". Мы провели достаточную подготовительную работу для разработки содержательныхзавершенных программ.

Здесь будет представлено три примера полностью завершенныхпрограмм, причем все они содержат массивы. В первом примере задача состоит в печати спискастепеней40двойки, причем каждая строка должна содержать величины 2^i, i, 2^(-i). Эта задача былабы очень простой, если использовать тип REAL. Тогда ядро программы выглядело бы так:d := 1; f := 1.0;FOR exp := 1 ТО N DOd := 2*d; печать(d); (* d = 2^exp *)печать(ехр);f := f/2.0; печать(f) (* f = 2^(-exp) *)ENDОднако мы хотим получить точные результаты с тем количеством цифр, котороепотребуется.

По этой причине мы представляем и целое число d = 2^ехр, и дробь f = 2^(-ехр)массивами "цифр", каждая из которых лежит в диапазоне 0...9. Для представления f нампотребуется N иифр, для d - только логарифм от N. Отметим, что удвоение d производится справаналево, а деление f пополам - слева направо. Таблица результатов приведена ниже.MODULE СтепениДвойки:FROM InOuL IMPORT Write,WriteLn,WriteString,WriteCard;CONST M = 11; N = 32; (* M ~ N*log(2) *)VAR i,j,k,exp: CARDINAL;c,r,t: CARDINAL:d: ARRAY [0..M] OF CARDINAL:f: ARRAY [0..N] OF CARDINAL:BEGINd[0] := 1; k := 1;FOR exp := 1 TO N DO(* вычислить d = 2^exp операциями d := 2*d *)с := 0; (* перенос *)FOR i := 0 TO k-1 DOt := 2*d[i] + c:IF t >= 10 THENd[i] := t - 10; с := 1ELSEd[i] := t; c := 0ENDEND;41IF с > О THENd[k] := 1; k := k + 1END:(* вывод d[k-1]...d[0] *) i := М;REPEAT i := i - 1; Write(" ") UNTIL i = k;:REPEAT i := i - 1; Write(CHR(d[i]+ORD("0")))UNTIL i = 0;WriteCard(exp,4);(* вычисление f = 2^(-exp) операциями f := f DIV 2и его вывод *)WriteString(" 0."); r : = 0; (* остаток *)FOR j := 1 ТО ехр-1 DOr := 10*r + f[j]; f[j] := r DIV 2:r := r MOD 2; Write(CHR(f[j]+ORD("0")))END;f[ехр] := 5; Write("5"); WriteLnENDEND СтепениДвойки.Вывод программы СтепениДвойки.21 0.542 0.2583 0.125164 0.0625325 0.03125646 0.0156251287 0.00781252568 0.003906255129 0.001953125102410 0.0009765625204811 0.00048828125409612 0.00024414062542819213 0.00012207031251638414 0.000061035156253276815 0.0000305175781256553616 0.000015258789062513107217 0.0000076293945312526214418 0.00000381469726562552428819 0.0000019073486328125104857620 0.00000095367431640625209715221 0.000000476837158203125419430422 0.ООО0ОО2384185791О15625838860823 0.0000001192092895507812516777216 24 0.00000005960464477539062533554432 25 0.000000029802322387695312567108864 26 0.00000001490116119384765625134217728 27 0.000000007450580596923828125268435456 28 0.0000000037252902984619140625536870912 29 0.000000001862645149230957031251073741824 30 0.0000000009313225746154785156252147483648 31 0.00000000046566128730773925781254294967296 32 0.00000000023283064365386962890625Наш второй пример имеет аналогичную природу.

Задача - точно вычислить десятичныедроби d - 1/1. Трудность заключается, конечно, в представлении дробей, которые являютсябесконечными последовательностями цифр (например, 1/3 = 0.333...). К счастью, все дроби имеютповторяющийся период, и было бы разумно и полезно отмечать начало периода и завершатьвычисление в его конце.

Но как находить начало и конец периода? Рассмотрим сначала алгоритмвычисления цифр дроби.Начиная с остатка ост = 10, мы повторяем умножение его на 10 и делим произведение на i.Частное от деления нацело - это новое значение для ост. Этот алгоритм в точности воспроизводитстандартный метод деления, что иллюстрируется следующим Фрагментом программы и числовымпримером при i = 7.1.000000 / 7 = 0.142857103020604043501ОСТ :- 1;REPEAT ост := 10*ост;СледЦиФра := ост DIV i;ост : = ост MOD 1UNTIL ...Мы знаем, что период завершится, как только получится остаток, который встречалсяранее.

Поэтому наш способ - запоминать остатки и их индексы. Индексы обозначают то место,откуда начинается период. Обозначим массив индексов через х и дадим его элементам начальныезначения 0. Индексация массива ведется по значениям остатков. В рассмотренном выше примеределения на 7 величины индексов следующие: х[1]=1, х[2]=3, х[3]=2, х[4]=5, х[5]=6, х[6]=4.MODULE Дроби;FROM InOut IMPORT Write,WriteLn,WriteString,WriteCard;CONST Основание = 10; N = 32;VARост: CARDINAL;i,j,m:CARDINAL;d:ARRAY[1..N]OFCARDINAL;(*цифры*)x:ARRAY[0..N]OFCARDINAL;(*индекс*)BEGINFORi:=2TONDOFORj:=0TOi-1DOx[j]:=0END;m:=0;ост:=1;REPEATm:=m+1;х[ост]:=m;ост:=Основание*ост;d[m]:=остDIVi;ост:=остMODiUNTIL х[ост] # 0;WriteCard(i,6);WriteString("FOR j := 1 TO х[ост]-1 DO Write(CHR(d[j]+ORD("0"))) END;0.");Write("'");FORWriteLnENDEND Дроби.j:=х[ост]TOmDOWrite(CHR(d[j]+ORD("0")))END;Вывод программы Дроби.2 0.5'0 З 0.'З4 0.25'05 0.2'0446 0.1'67 0.'1428578 0.125'09 0.'1 10 0.1'0 11 0.0812 0.08'313 0.'07692314 0.0'71428515 0.0'616 0.0625'017 0.'058823529411764718 0.0'519 0.'05263157894736842120 0.05'0 21 0.'04761922 0.0'4523 0.'043478260869565217391324 0.041'625 0.04'026 0.0'38461527 0.'03728 0.03'57142829 0.'034482758620689655172413793130 0.0'331 0.'03225806451612932 0.03125'0В последнем примере рассмотрим программу печати списка простых чисел.

Онаосновывается на проверке делимости последовательных целых чисел. Проверяемые целые числаполучаются увеличением предыдущего числа по очереди на 2 и на 4. тем самым сразу отсекаютсячисла, кратные 2 и 3. Необходимо проверять делимость только на простые числа, которые былиуже ранее вычислены и запомнены.MODULEFROM InOut IMPORT WriteLn,WriteCard;CONSTN=250;M=LL = 8; (* сколько простых чисел печатать на строке *)ПростыеЧисла:16;(*M^2~N*)45VARшаг,граница,квадрат,L:простое:P,V:ARRAYBEGINLx:=1;шаг:=4;FORi:=(*найтиследующееREPEATx:=x+IF квадрат <= х THENграницаквадратEND;k:-[0..M]граница3простоешаг;граница:-:=простое:=V[k]:=WHILEkIFV[k]ENDi,k,x:+1;2;&OF:=:=1:TOчислошаг:=V[гpaница]:квадрат;Р[граница+1]*Р[граница+1]простое(k:=граница)<k<V[k]простоеCARDINAL;CARDINAL;BOOLEAN;CARDINAL;0;квадрат:=9;NDOР[i]*)6шаг;+x+:=x#TRUE;DO1;THEN2*P[klV[k]ENDUNTIL простое:IFiWriteCard(x,6);IFWriteLn;ENDENDEND ПростыеЧисла.<=MLLTHEN:=Р[i]L:=LL:=Lх+END;1:THEN0Вывод программы ПростыеЧисла.57111317 19 23293137414347 53 59616771737983 89 97101103107109113127 131137139149151157163167 173179181191193197199211 223227229233239241251257 263269271277281283293307 311313317331337347349353 359367373379383389397401 409419421431433439443449 457461463467479487491499 50350952146523541547557563 569571577587593599601607 613617619631641643647653 659661673677683691701709 719727733739743751757761 769773787797809811821823 827829839853857859863877 881883887907911919929937 941947953967971977983991 9971009101310191021103110331039 10491051106110631069108710911093 10971103110911171123112911511153 11631171118111871193120112131217 12231229123112371249125912771279 12831289129112971301130313071319 13211327136113671373138113991409 14231427142914331439144714511453 14591471148114831487148914931499 15111523153115431549155315591567 15711579158315971601Эти примеры завершают первую часть книги.Они показывают, что массивыявляются фундаментальным средством, используемым в большинстве программ.

Характеристики

Тип файла
PDF-файл
Размер
2,76 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6314
Авторов
на СтудИзбе
312
Средний доход
с одного платного файла
Обучение Подробнее