Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник.docx
Скачиваний:
36
Добавлен:
21.12.2018
Размер:
2.15 Mб
Скачать

Перевод римских чисел в арабские. Пример автоматного распознавателя Задача:

Можно использовать вложенные операторы case. Это удобно, например, при реализации автоматных распознавателей, которые дают способ наглядной записи алгоритмов распознавания текстов.

Представленная таблица предназначена для перевода римских чисел, составленных из цифр X, V, I.

Алгоритм решения задачи:

 

X

V

I

1

n := 10; state := 2

n := 5; state := 3

n := 1; state := 6

2

n := n + 10; state := 2

n := n + 5; state := 3

n := n + 1; state := 6

3

ok := false

ok := false

n := n + 1; state := 4

4

ok := false

ok := false

n := n + 1; state := 5

5

ok := false

ok := false

n := n + 1; state := 7

6

n := n + 8; state := 7

n := n + 3; state := 7

n := n + 1; state := 5

7

ok := false

ok := false

ok := false

Первый столбец (цифры от 1 до 7) – это состояния (state).

Для расшифровки XIV начинаем с состояния 1. Первый символ – ‘X’, поэтому смотрим столбец ‘X’ и находим n := 10; state := 2. Итак, полагаем n равным 10 и сдвигаем стрелку на вторую строку. Теперь смотрим столбец, определяемый вторым символом, т.е. ‘I’, и находим n := n + 1; state := 6. Значение n, таким образом, становится 10 + 1 = 11. Сдвигаем стрелку к строке 6. Теперь в столбце ‘V’ находим n := n + 3; state := 7. Значение n становится равным 11 + 3 = 14. Сдвигаем стрелку на строку 7 и замечаем, что любая следующая цифра ‘X’, ‘V’ или ‘I’ будет теперь ошибкой (чисел XIVX, XIVV, XIVI не может быть).

Эта таблица позволяет декодировать римскую запись чисел, содержащих любое количество цифр X (в начале) и цифры V, I, записанные по обычным правилам:

I, II, III, IV, V, VI, VII, VIII, IX, X, XI и т.д.

Вместе с тем такое число как IIII будет воспринято как ошибочное и переменная ok примет значение false. Для работы с цифрами M, D, C и L таблицу можно расширить.

Программа на языке Паскаль:

var

n, state: integer;

symbol: char;

ok: boolean;

begin

state := 1;

ok := true;

n := 0;

while not eoln do begin

read(symbol);

if ((symbol = 'X') or (symbol = 'V') or (symbol = 'I')) then

case state of

1: case symbol of

'X': begin n := 10; state := 2 end;

'V': begin n := 5; state := 3 end;

'I': begin n := 1; state := 6 end

end;

2: case symbol of

'X': begin n := 10; state := 2 end;

'V': begin n := n + 5; state := 3 end;

'I': begin n := n + 1; state := 6 end

end;

3: case symbol of

'X', 'V': ok := false;

'I': begin n := n + 1; state := 4 end

end;

4: case symbol of

'X', 'V': ok := false;

'I': begin n := n + 1; state := 5 end

end;

5: case symbol of

'X', 'V': ok := false;

'I': begin n := n + 1; state := 7 end

end;

6: case symbol of

'X': begin n := n + 8; state := 7 end;

'V': begin n := n + 3; state := 7 end;

'I': begin n := n + 1; state := 5 end

end;

7: ok := false;

end

else begin

if ok then

writeln(n:2)

else

writeln('error');

state := 1;

ok := true

end;

end;

readln

end.

Примечания:

Программа не выдает ошибок, но и не работает.