47790 (608374), страница 4
Текст из файла (страница 4)
-командой остановки.
Число i, стоящее в начале команды, называется номером команды. Так, у приведенных только что команд номера соответственно 137, 25 и 6386. Число j, стоящее в конце команды (а у команд передачи управления - каждое из чисел j1, и j2), будем называть отсылкой (при этом в команде передачи управления j1—верхней, а j2 — нижней отсылкой). У команд остановки нет отсылки. Так, у приведенных только что команд отсылками служат числа 1, 32, 25, причем 32 —верхняя отсылка, а 25 — нижняя отсылка.
Программой машины Поста будем называть конечный непустой (т. е. содержащий хотя бы одну команду) список команд машины Поста, обладающий следующими двумя свойствами:
1) На первом месте в этом списке стоит команда с номером 1, на втором месте (если оно есть) – команда с номером 2 и т. д.; вообще на k-м месте стоит команда с номером k.
2) Отсылка любой из команд списка совпадает с номером некоторой (другой или той же самой) команды списка (более точно: для каждой отсылки каждой команды списка найдется в.списке такая команда, номер которой равен рассматриваемой отсылке).
Например, следующий список будет программой машины Поста:
А эти два списка не будут программами машины Поста, хотя и составлены из команд машины Поста:
Для наглядности программы машины Поста мы будем записывать столбиком. Число команд программы называется длиной программы[1].
Работа машины Поста
Чтобы машина Поста начала работать, надо задать, во-первых, некоторую программу, а во-вторых, некоторое ее (машины) состояние, т. е. как-то расставить метки по секциям ленты (в частности, можно все секции оставить пустыми) и поставить каретку против одной из секций. Как правило, мы будем предполагать, что в начальном (т.е. в задаваемом вначале) состоянии машины каретка ставится всегда против секции с номером (координатой) нуль. При таком соглашении начальное состояние машины полностью определено состоянием ленты.
Как уже говорилось, программа является той инструкцией, на основании которой работает машина. Работа машины на основании заданной программы (и при заданном начальном состоянии) происходит следующим образом. Машина приводится в начальное состояние и приступает к выполнению первой команды программы. Эта команда выполняется за один шаг, после чего машина приступает к выполнению той команды, номер которой (назовем его а) равен отсылке (одной из отсылок, если их две) первой команды. Эта команда также выполняется за один шаг, после чего начинается выполнение команды, номер которой равен отсылке команды с номером а. Вообще каждая команда выполняется за один шаг, а переход от выполнения одной команды к выполнению другой происходит по следующему правилу: пусть на k-м шаге выполнялась команда с номером i, тогда, если эта команда имеет единственную отсылку j, то на k+1-м шаге выполняется команда с номером j; если эта команда имеет две отсылки j1 и j2, то на k+1-м шаге выполняется одна из двух команд – с номером j1 или с номером; если, наконец, выполняющаяся на k-м шаге команда вовсе не имеет отсылки, то на k + 1-м шаге и на всех последующих шагах не выполняется никакая команда: машина останавливается. Осталось объяснить, что значит выполнить команду и какая из отсылок - при наличии двух - выбирается в качестве номера следующей команды.
Выполнение команды движения вправо состоит а том, что каретка сдвигается на одну секцию вправо. Выполнение команды движения влево состоит в том, что каретка сдвигается на одну секцию влево. Выполнение команды печатания метки состоит в том, что каретка ставит метку на обозреваемой секции; выполнение этой команды возможно лишь в том случае, если обозреваемая перед началом выполнения команды секция пуста; если же на обозреваемой секции уже стоит метка, команда считается невыполнимой. Выполнение команды стирания метки состоит в том, что каретка уничтожает метку в обозреваемой секции; выполнение этой команды возможно лишь в том случае, если обозреваемая секция отмечена; если же на обозреваемой секции и так нет метки, команда считается невыполнимой. Выполнение команды передачи управления с верхней отсылкой j1 и нижней отсылкой j2 никак не изменяет состояния машины: ни одна из меток не уничтожается и не ставится, и каретка также остается неподвижной (машина делает, так сказать, «шаг на месте»); однако если секция, обозреваемая перед началом выполнения этой команды, была пуста, то следующей должна выполняться команда с номером j1, если же эта секция была отмечена, следующей должна выполняться команда с номером j2 (роль команды передачи управления сводится, следовательно, к тому, что каретка во время выполнения этой команды как бы «распознает», стоит ли перед ней метка). Выполнение команды остановки тоже никак не меняет состояния машины и состоит в том, что машина останавливается.
Если теперь, задавшись программой и каким-либо начальным состоянием, пустить машину в ход, то осуществится один из следующих трех вариантов:
1) В ходе выполнения программы машина дойдет до выполнения невыполнимой команды (печатания метки в непустой секции или стирания метки в пустой секции); выполнение программы тогда прекращается, машина останавливается; происходит так называемая безрезультатная остановка.
2) В ходе выполнения программы машина дойдет до выполнения команды остановки; программа в этом случае считается выполненной, машина останавливается; происходит так называемая результативная остановка.
3) В ходе выполнения программы машина не дойдет до выполнения ни одной из команд, указанных в первых двух вариантах; выполнение программы при этом никогда не прекращается, машина никогда не останавливается; процесс работы машины происходит бесконечно[5].
Глава 2. Инструкция программиста
Данная учебная программа должна запускаться на IBM и совместимых компьютерах. Минимальные системные требования: процессор Pentium и выше, объем оперативной памяти 16MB, видеокарта с расширением 800x600, 256 цветов, операционная система семейства Windows 95 и выше, на компьютере также должен быть установлен .NET Framework.
Основную ценность представляют файлы расширением *.cs (в них содержится весь код программы).
Опишем основные файлы, содержащиеся в этой папке:
-
Even_ueven.cs – файл, в котором содержится код, отвечающий за работу алгоритма «Кодирование по методу четности\нечетности»;
-
Even_ueven.resx – файл, в котором содержится информация о графическом представлении формы «Кодирование по методу четности\нечетности»;
-
Hemming.cs - файл, в котором содержится код, отвечающий за работу алгоритма «Кодирование по методу Хэмминга»;
-
Hemming.resx – файл, в котором содержится информация о графическом представлении формы «Кодирование по методу Хэмминга»;
-
Post.cs - файл, в котором содержится код, отвечающий за работу алгоритма «Программирование машины Поста»;
-
Post.resx – файл, в котором содержится информация о графическом представлении формы «Программирование машины Поста»;
-
Error.cs - файл, в котором содержится код, отвечающий за работу формы Error;
-
Error.resx – файл, в котором содержится информация о графическом представлении формы Error;
-
Help.cs - файл, в котором содержится код, отвечающий за работу формы Справка;
-
Help.resx – файл, в котором содержится информация о графическом представлении формы Справка;
-
Start.cs - файл, в котором содержится код, отвечающий за работу формы Start;
-
Start.resx – файл, в котором содержится информация о графическом представлении формы Start;
-
AssemblyInfo.cs - файл, в котором содержится информация о версии файла, внутреннем и исходном имени файла, производителе;
-
StudyProgram.exe - закомпилированный файл программы, находящийся в папке debug, которая находится в папке bin.
Для изменения программы необходимо изменить ее исходный код. Это можно сделать, используя любой текстовый редактор. Пример кода представлен на Рис.2.
Изменение кода при помощи текстового редактора не очень удобно, для этого лучше использовать Visual Studio .Net, специально для этого разработанный.
На Рис.3 можно увидеть внешний облик Visual Studio .Net. Для его запуска необходимо кликнуть кнопку Пуск, выбрать в пункте Все программы \Microsoft Visual Studio .NET 2003\Microsoft Visual Studio .NET 2003. Далее в запустившемся приложении кликнуть кнопку Open Project и используя проводник, выбрать файл Study_Programs.sln. Программа откроет приложение. Для изменения внешнего вида программы необходимо воспользоваться ярлыком Design. Можно добавить новые элементы формы, перетащив их из выезжающего окна Toolbox. Исходный код программы см. в Приложении.
В самом начале программы задаются поля, так называемые член- переменные, содержащие некоторое значение: int Prav; int ch; int ChVoprosov=1 (в ООП поля иногда называют данными объекта).Где Prav-это количество правильных ответов, ch – это сумма всех разрядов генерируемого числа и контрольного разряда, а ChVoprosov-число вопросов заданных пользователю (нумерация начинается с 1) Перед идентификаторами полей указываются их типы.
При запуске формы Even_ueven во время работы программы сразу срабатывает метод Generation(); .Суть данного метода состоит в том, чтобы сгенерировать произвольное семизначное двоичное число, которое появится в окне textBox1 и контрольный разряд(который также является двоичным числом), который появится в окне textBox2. Для этого создается генератор случайных чисел, который записывает в переменную d либо 0, либо 1( d=r.Next(0,2); ), данная операция повторяется 7 раз с помощью цикла с параметром for( for (int i=0; i<7; i++) ). В результате, последовательно добавив каждую из сгенерированных цифр, мы получаем требуемое семизначное число. Контрольный разряд создается тоже с помощью генератора случайных чисел ( g=r.Next(0,2); ).Также в этом методе сразу подсчитывается сумма всех разрядов генерируемого числа и контрольного разряда ch: сначала складываются разряды числа все в том же цикле for (ch+=d; - 7 раз), а затем прибавляется контрольный разряд g (ch+=g;).
При нажатии кнопки button1 (Код числа правильный) вначале запускается метод ChangeChVoposov(); который увеличивает номер вопроса на одну единицу в окне textBox3. Затем в поле Prav(количество правильных ответов) считывается значение из окна textBox4( при первом запуске оно равняется 0), Далее с помощью управляющей конструкции if (ch==0 || ch==2 || ch==4 || ch==6) определяется правильно ли пользователь ответил : ch - сумма всех разрядов генерируемого числа и контрольного разряда должна быть четной или равной 0. В случае верного выбора количество правильных ответов увеличивается на 1 ( Prav++; ). Затем запускается метод ChangePrav();, который устанавливает число правильных ответов в окне textBox4. После чего ch обнуляется ( ch=0; ) , и запускается метод Generation();.
При нажатии кнопки button2 (Код числа неправильный) алгоритм программы является практически аналогичным за исключением того, что в управляющей конструкции if (ch==1 || ch==3 || ch==5 || ch==7) правильность ответа пользователя заключается в том, чтобы сумма ch являлась нечетным числом.
Также следует обратить внимание на то, что при работе с дизайном формы нужно заблокировать окна от пользователя, чтобы он не смог перепечатать значение генерируемых семиразрядного числа и контрольного разряда, а также количество заданных вопросов и данных правильных ответов. Исходный код программы представлен в Приложении.
Кодирование по методу Хэмминга
В самом начале программы задаются поля: int ChVoprosov=1,
int X; int Nomer; int [] x=new int[10] .Где X – это переменная значение которой не позволяет в определенных случаях нажиманием на одну и ту же кнопку увеличивать число правильных ответов, Nomer – это получаемый номер разряда, который подлежит замене на противоположный, int [] x=new int[10] – это массив, состоящий из значений, которые являются разрядами генерируемого двоичного числа, а ChVoprosov-число вопросов заданных пользователю (нумерация начинается с 1). Перед идентификаторами полей указываются их типы.
При запуске формы Hemming во время работы программы сразу срабатывает метод Generation(); и метод Number(); .Суть первого метода состоит в том, чтобы сгенерировать произвольное девятизначное двоичное число, которое появится в окне textBox1. Суть второго метода заключается в том, чтобы подсчитать номер разряда, в котором есть ошибка (если конечно такова вообще имеется). Следует учесть, что номер подсчитывается в двоичном виде.
Для формирования произвольного девятизначного двоичного числа создается генератор случайных чисел, который записывает в переменную d либо 0, либо 1( d=r.Next(0,2); ), данная операция повторяется 9 раз с помощью цикла с параметром for( for (int i=1; i<10; i++) ). В результате, последовательно добавив каждую из сгенерированных цифр, мы получаем требуемое девятизначное число. Также на каждом шаге цикла с параметром считываются значения в массив int [] x ( x[i]=d; ), т.е. получается , что каждый элемент массива равен соответствующему по номеру разряду сгенерированного числа. В данном методе переменная X приравнивается к 1, что означает, что число только что сгенерированно и пользователь еще не пробовал дать свой ответ.
В методе Number() подсчитываются суммы контрольных разрядов сгенерируемого по числа, соответствующие определенным группам проверки. В нашем случае количество групп проверки для девятизначного числа равно 4, следовательно, мы получаем четыре суммы x1, x2, x3, x4.
Затем подсчитывается номер ошибочного разряда (Nomer=x4*1000+x3*100+x2*10+x1;)
При нажатии кнопки button1 (Ошибки нет) в начале исчезает все то, что пользователь успел ввести в окно «Исправленный вариант» (textBox2.Text="";), т.к. нажав эту кнопку пользователь показывает то, что он уже не находит ошибок в числе. Потом с помощью управляющей конструкции if проверяется не записан ли уже ответ в окне «Правильный ответ»( if(textBox1.Text.Length!=textBox3.Text.Length) ели не записан, то тогда X приравнивается к единице: X=1;) Затем с помощью управляющей конструкции if проверяется, равен ли X единице (if (X==1) – если это выполнено, то значит, что пользователь еще не пробовал дать свой ответ). Дальнейшее выполнение действий возможно только если X=1. Затем, используя снова if, Nomer сравнивается с нулем (if (Nomer==0)). В случае выполнения данного условия (т.е. номер ошибочного разряда равняется нулю, что означает отсутствие ошибки) число правильных ответов увеличивается на одну единицу ( Prav++; ), и запускается метод Otvet(); . Данный метод записывает в окно textBox3 (Правильный ответ) ответ, получаемый путем записи всех элементов массива int [] x в порядке возрастания:
textBox3.Text=x[1]+""+x[2]+""+x[3]+""+x[4]+""+x[5]+""+[6]+""+x[7]+""+x[8]+""+x[9];
В данном случае ошибка отсутствует и все элементы запишутся без изменения, т.е. в окне textBox3 появится число, аналогичное тому, которое находится в окне textBox1 (Число, возможно содержащее ошибку).
Если Nomer не равняется нулю, то тогда запускается метод Sravnenie();. Этот метод вначале проверяет не дали ли вы уже свой окончательный ответ (не равно ли уже X нулю) и только в случае равенства X единице (if (X==1)) выполняется вся остальная часть метода: переменную i приравнивают т к нулю (int i=0;). Затем происходит сравнение числа Nomer с двоичными цифрами, которые при переводе в десятичную систему счисления соответствуют числам от 0 до 9 (например: if (Nomer == 101) – число Nomer сравнивается с двоичным числом 101, которому в десятичной системе счисления соответствует 5). Если Nomer равняется какому-то из предложенных двоичных чисел, то тогда переменной i присваивается значение соответствующего десятичного числа (Например в случае равенства номера числу 101, переменной i присвоится значение 5 (i = 5;)). Если переменная i меняет свое значение с нуля на какое-то от 1 до 9, то тогда выполняется условие следующей за этим управляющей конструкции if (i!=0) (i отлично от нуля) и осуществляется следующие операции: x[i] сравнивается с 0, если это выполняется, то тогда x[i] меняет свое значение на противоположное, т.е. на 1, и затем запускается уже упомянутый выше метод Otvet(); (только теперь в окне textBox3 появится число, аналогичное тому, которое находится в окне textBox1 (Число, возможно содержащее ошибку), но уже с замененным на противоположный разрядом, номер которого равен i.). Если x[i] не равняется 0(следовательно равняется 1), то тогда выполняется ветка else с аналогичными действиями, только для x [i] противоположным значением будет являться 0.
Если в ходе выполнения метода Sravnenie(); не было произведено никаких замен (не выполнялся метод Otvet();), то это означает, что числу Nomer соответствует какое-то двоичное число, которое при переводе в десятичную систему счисления дает цифру большую 9. Это означает, что в сгенерированном девятиразрядном числе отсутствуют ошибки. Тогда с помощью сравнения длины строки в окне textBox3 с нулем (if(textBox3.Text.Length==0)) мы получаем в случае выполнения данного условия, что ошибки отсутствуют. Следовательно, мы можем увеличить число правильных ответов на 1 и запустить метод Otvet();,который запишет в окно textBox3 число, равное тому, которое находится в окне textBox1 (Число, возможно содержащее ошибку).
7>10>














