Средства языка Паскаль для программирования разветствляющихся алгоритмов
Таблицу ситуаций удобно было бы уточнять с помощью команды выбора следующего вида (на Псевдокоде):
Выбрать
при ситуация 1: действие 1;
при ситуация 2: действие 2;
...
при ситуация n: действие n;
Все.
Алгоритм выполнения этой команды выбора следующий (здесь уже порядок действий важен):
1). Просмотреть все ситуации в записанном порядке сверху вниз;
2). При совпадении текущей ситуации с одной из ситуаций из приведенного (в команде выбора) списка выполнить действия, соответствующие данной ситуации;
3). После выполнения действий для конкретной ситуации все оставшиеся строки в команде выбора пропускаются, т.е. выполняется переход к слову все;
4). Если текущая ситуация не совпадает ни с одной ситуацией из приведенного списка, то команда выбора игнорируется (пропускаются все действия в ней)).
К сожалению в том виде, в котором мы команду выбора записали, она не поддерживается ни Паскалем, ни другими языками программирования. На Паскале последней команде выбора соответствует следующий оператор:
одиночный оператор или составной оператор |
константа константа1, константа2, константа3, …. диапазон |
Case C of
набор1: оператор1;
набор2: оператор2;
...
наборn: операторn;
end
Переменная "селектор" (ее начения рассматриваются как признаки наступления ситуаций) может быть любого порядкового типа. Особенность данного вида команды выбора состоит в том, что одна ситуация от другой отличается по набору значений этой переменной. Существуют следующие случаи задания таких наборов:
1-й случай: указывается просто одна константа (порядкового типа)
2-й случай: указывается несколько констант, разделенных запятыми
3-й случай: указывается диапазон значений (констант)
4-й случай: комбинация первых трех случаев.
Замечание1: Переменная селектор на Паскале может быть любого порядкового типа, кроме longint.
Замечание2: После каждого двоеточия вы можете написать действие только из одного оператора. В случае необходимости записать несколько операторов нужно заключать эти операторы в операторные скобки (begin - end).
ПРИМЕР: Стоит задача для введенного символа вывести на экран информацию о том, какой это символ: буква (для простоты примера - латинская) или цифра?
var
C:char;
Begin
Write(‘Введите символ: ’);
readln(C);
Case C of
‘A’..’Z’,’a’..’z’: writeln(‘Это буква’);
‘0’..’9’: writeln(‘Это цифра’);
end;
End.
Дополним текст этой программы, чтобы постараться увеличить число распознаваемых ситуаций ( 1 – цифра, 2 – буква, 3 – строчная буква, 4 – прописная буква):
var
C:char;
Begin
Write(‘Введите символ: ’);
readln(C);
Case C of
‘0’..’9’ : writeln(‘ -->’, C, ‘ – это цифра’);
‘A’..’Z’,’a’..’z’: writeln(‘ -->’, C, ‘ – это буква’);
’a’..’z’ : writeln(‘ -->’, C, ‘ – это строчная буква’);
‘A’..’Z’ : writeln(‘ -->’, C, ‘ – это прописная (заглавная) буква’);
end;
End.
Вопрос: если будет введен символ, например ‘d’, то что будет выведено на экран?
Ответ: для выделенные строки будет выдаваться сообщение компилятора типа
«Duplicate case label».
Дело все в том, что наборы не должны пересекаться, иначке компилятор будет ругаться про дублирование констант.
Вопрос: как же написать, чтобы выводилась информация и о том, что символ есть буква, и о том, какая это буква – строчная или прописная? Ответ - никак.
Если число ситуаций не превышает двух и ситуации взаимоисключающие, то целесообразно для уточнения таблицы ситуаций использовать не команду выбора, а команду ветвления следующего вида: описание ситуации (в виде логического выражения)
if ситуация
then действие 1 //для ситуации 1
else действие 2 //для ситуации 2
Ситуации | Действия |
Ситуация 1 имеет место | действие 1 |
Ситуация 1 не наступила | действие 2 |
Этой команде соответствует следующая таблица ситуаций и схема алгоритма:
значит, наступила ситуация 2
(если ситуации взаимоисключающие)
Если при не наступлении ситуации никаких действий выполнять не нужно, то можно использовать сокращенную форму записи команды ветвления:
| Действия | |
ситуация имеет место | действие 1 | |
ситуация не наступила | - (пусто) |
На Паскале команде ветвления соответствует условный оператор (оператор if):
Замечание 1: При записи условного оператора на Паскале наиболее частой ошибкой является запись ';' перед else. Точка с запятой пишется после then только при отсутствии else.
Замечание 2: После then и else можно указать только один оператор, если нужно использовать несколько операторов, то нужно использовать операторные скобки (begin – end).
Замечание 3: else всегда соответствует самому ближайшему выше по тексту программы оператору if, не имеющему части else. Для явного указания того, к какому if из последовательности относится else у программиста есть два пути:
1) использовать else с пустым оператором в качестве действия в тех вышестоящих (относительно нашего else) операторах if, к которым мы не хотим отнести данный else.
2) использовать операторные скобки для обозначения границ действий по ветвям then и else для каждого оператора if.
Пример:
if (C1)
then if (C2)
then D1
else D2;
Вопрос: как сделать, чтобы D2 относился не к С2, а к С1?
1-й вариант if (C1) then if (C2) then D1 else ; <-- не ставить ‘;’ else D2 2-й вариант if (C1) then begin if (C2) then D1 end ; <-- не ставить ‘;’ else D2 |
13.3 Виды ситуаций.
Ситуации бывают зависимыми и независимыми.
Независимые - это такие ситуации, наступление или не наступление которых не зависит от наступления каких-либо других ситуаций. Зависимые - это такие ситуации, наступление или не наступление которых зависит от наступления каких-либо других ситуаций.
Независимые ситуации могут иметь место одновременно (а зависимые – нет). Дело в том, что независимые ситуации обычно разнесены по различным подзадачам. Исходя из этого независимые ситуации вместе (в рамках одной подзадачи) обычно не рассматриваются.
Все ситуации, упомянутые ранее в таблице ситуаций, являются зависимыми. Кроме того, ситуации, рассмотренные в таблице ситуаций, должны быть взаимоисключающими, т.е. подчиняются следующим трем правилам:
1) Эти ситуации образуют полную группу событий в том смысле, что из этой группы нельзя без потери смысла выкинуть и добавить ситуацию.
2) В каждый конкретный момент времени имеет место только одна ситуация из списка .
3) В случае отсутствия признаков наступления (n-1)-ной из n ситуаций можно гарантированно сделать вывод о наступлении n-ой ситуации.
Последнее означает, что для n взаимоисключающих ситуаций в команде выбора достаточноописать (n-1) ситуацию.
С учетом сказанного более полная форма команды выбора на Паскале имеет следующий вид:
case имя of
набор 1: оператор 1;
набор 2: оператор 2;
...
набор n-1: оператор n-1 ;
else оператор n ;
end; можно ставить, а можно и не ставить
действия в случае отсутствия признаков наборов с 1 по n
(необязательная конструкция)
Соответственно, для приведенного выше примера распознавания типа введенного символа оператор CASE мог бы иметь следующий расширенный вид:
var
C:char;
Begin
Write(‘Введите символ: ’);
readln(C);
Case C of
‘A’..’Z’,’a’..’z’: writeln(‘Это буква’);
‘0’..’9’ : writeln(‘Это цифра’);
else writeln(‘Неизвестный символ’);
end;
End.
Рассмотрим Пример. Пусть необходимо распознать треугольник по трем его сторонам. Пусть стороны называются a, b, c. Результатом анализа должен являться вывод сообщения на экран о конкретном виде треугольника.
if тр-к сущ-ет then определить вид тр-ка else writeln(‘Тр-к не существует’); |
Ситуация | Действие |
Треугольник существует | Определить вид треугольника |
Треугольник не существует | Сообщение := 'Треугольник не существует' |
{Определение вида тр-ка} if тр-к равностор. then writeln(‘Тр-к равностор.’) else if тр-к равнобедр. then writeln(‘Тр-к равнобедр.’) else writeln(‘Тр-к произв.’); |
Ситуация | Действие |
Треугольник равностор. | Сообщение := 'Треугольник равносторонний' |
Треугольник равнобедр. | Сообщение := 'Треугольник равнобедренный' |
Треугольник произвол. | Сообщение := 'Треугольник произвольный' |
Построим итоговый алгоритм.
операторы IF вкладываются один в другой
В итоге получим:
if (треугольник существует)
then
if (треугольник равносторонний)
then writeln(‘Этот треугольник равносторонний’)
else
if (треугольник равнобедренный)
then writeln(‘Этот треугольник равнобедренный’)
else writeln(‘Этот треугольник имеет произвольную форму’)
else writeln(‘Такого треугольника не существует’);
Замечание: из данного примера видно, что для каждой таблицы ситуаций число уточняющих ее операторов if должно быть равно (число ситуаций в таблице) - 1.
Описание ситуаций
Как уже отмечалось, на начальных этапах разработки алгоритма в описании ситуации может использоваться название ситуации типа «Треугольник равносторонний», «Треугольник равнобедренный». Однако в общем случае описание ситуации нужно рассматривать как некоторое высказывание или утверждение, о котором можно сказать, что оно истинно или ложно.
Истинность или ложность ситуации должна определяться по определенному для данной ситуации набору значений т.н. признаков ситуации. В частном случае у ситуации может быть только один признак.
В общем случае поиск описания ситуации в первую очередь идет в направлении выявления признаков ситуации, определения их соотношения, а затем - в направлении уточнения (формальной записи) признаков и их соотношения. Уточнение признаков идет до тех пор, пока они не примут вид операции отношения (a>b, x=y) или логических переменных.
Признаки могут быть необходимыми и достаточными.
Необходимый признак - это такой признак, при отсутствии которого ситуация не наступит никогда (даже при наличии других признаков).
Достаточный признак - такой признак, при наличии которого ситуация обязательно наступит (даже при отсутствии других признаков).
В описании ситуации необходимые признаки соединяются союзом И (and).
Достаточные признаки в описании ситуации объединяются союзом ИЛИ (or).
С учетом этих замечаний о признаках ситуации уточним ситуацию в задаче с анализом треугольника.
Ситуация1: треугольник существует
Признаки: соотношение между суммой 2-x сторон и 3-ей стороной.
((a + b) > c) И ((a + c) > b) И ((b + c) > a) .
П1 AND П2 AND П3 = треугольник существует
Каждый из этих признаков является необходимым (но не является достаточным - можно рассмотреть признаки человека и курицы - 2 ноги, голова, и т.п.), поэтому они соединяются союзом "И" (and).
Ситуация2: треугольник равносторонний. ЛИШНИЙ
Признаки: равенство сторон (a = b) и (b = c) и (a = c) .
П1 and П2 and П3 = треугольник равносторонний
Все признаки являются необходимыми (но не являются достаточными), но один из них является избыточным.
Ситуация3: треугольник равнобедренный.
Признаки:
(a = b) или (b = c) или (a = c)
П1 OR П2 OR П3 = треугольник равнобедренный.
С учетом этого уточнения можно переписать команды выбора, и они примут следующий вид:
if ((a + b) > c) and ((a + c) > b) and ((b + c) > a)) then {треугольник существует} if ((a = b) and (b = c)) then writeln(‘Этот треугольник равностор.’) else if ((a = b) or (b = c) or (a = c)) then writeln(‘Этот треугольник равнобедр.’) else writeln(‘Этот треугольник произв.’) else {треугольник не существует} writeln(‘Такого треугольника не существует’); |
Дата добавления: 2016-05-28; просмотров: 1857;