Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метода по ОАиП.doc
Скачиваний:
12
Добавлен:
11.05.2015
Размер:
3.21 Mб
Скачать

15.6. Построение обратной польской записи

Сложные вычислительные задачи обычно требуют больших объемов вычислений, поэтому к разработчикам языков программирования было предъявлено требование: максимально приблизить форму записи математических выражений в коде программы к естествен­ному языку математики.

Одну из первых областей системного програм­мирования составили исследования способов трансляции математических выражений.

В результате наибольшее распространение получил метод трансляции при помощи обратной польской записи, которую предложил польский математик Я. Лукашевич.

Рассмотрим алгоритмы получения обратной польской записи с использованием структур в виде дерева и стека.

15.6.1. Алгоритм, использующий дерево

Данный алгоритм основан на представлении математического выражения в виде дерева и использовании третьего способа его обхода (см. п. 15.5.6). Напомним его на примере арифметического выражения (A+B)*(C+D)–E.

Представим это выражение в виде дерева, в котором узлам соответствуют операции, а листьям – операнды. Построение начинается с корня, в качестве которого выбирается последняя выполняемая операция. Левой ветви соответствует левый операнд операции, а правой ветви – правый. Дерево выражения имеет вид:

Совершим обход дерева, под которым понимается формирование строки из символов узлов и ветвей дерева. Обход будем совершать от самой левой ветви вправо и узел переписывать в выходную строку только после рассмотрения всех его ветвей. Обход совершаем строго по уровням:

1) уровень 2: АВ+CD+

2) поднялись на уровень 1:

3) и, наконец, корень:

В результате такого обхода получили обратную польскую запись:

AB+CD+*E (15.1)

15.6.2. Алгоритм, использующий стек

Получение обратной польской записи с использованием стека может осуществляться весьма просто на основе алгоритма, предложенного Дейкстрой, который ввел понятие стекового приоритета операций:

Операция

Приоритет

(

1

+ –

2

* /

3

Суть алгоритма в следующем. Просматривается исходная строка символов S слева направо, операнды переписываются в выходную строку В, а знаки операций заносятся в стек, который первоначально пуст, на основе следующих правил:

1) если в строке Sвстретился операнд, то помещаем его в строкуВ;

2) если в Sвстретилась открывающая скобка, то помещаем ее в стек;

3) если в Sвстретилась закрывающая скобка, то выталкиваем из стека в строкуВвсе операции до открывающей скобки, саму отрывающую скобку также извлекаем из стека; обе скобки (открывающая и закрывающая) игнорируются;

4) если в Sвстретилась операцияХ, то выталкиваем из стека все операции, приоритет которых не нижеХ, после чего операциюХзаписываем в стек;

5) при достижении конца строки S, если стек не пуст, переписываем его элементы в выходную строкуВ.

Обратная польская запись обладает рядом замечательных свойств, которые превращают ее в идеальный промежуточный язык при трансляции.

Во-первых, вычисление выражения, записанного в обратной польской записи, может проводиться путем однократного просмотра, что является весьма удобным при генерации объектного кода программ.

Например, вычисление полученного выражения (15.1) может быть проведено следующим образом:

Шаг

Анализируемая строка

Действие

1

AB+CD+*E–

R1=A+B

2

R1CD+*E–

R2=C+D

3

R1 R2*E–

R1=R1*R2

4

R1 E–

R1=R1–E

5

R1

Здесь R1 и R2 – вспомогательные переменные.