Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
всё для проги / Программирование на ЯВУ-Снижко / Динамические структуры данных.doc
Скачиваний:
104
Добавлен:
26.03.2015
Размер:
397.31 Кб
Скачать

Пример использования стеков: постфиксная, префиксная и инфиксная записи

Префиксы «пре», «пост» и «ин» относятся к относительной позиции оператора по отношению к операндам. В префиксной записи операция предшествует операндам, в постфиксной следует за операндами, а в инфиксной записи операция разделяет два операнда.

А + В – инфиксная запись

А В + – постфиксная запись

+ А В – префиксная запись

Вычисление выражения А + В * С, записанное в стандартной инфиксной записи, требует знания того, какая из двух операций выполняется первой. В случае + и * мы знаем, что умножение выполняется раньше сложения (при отсутствии скобок). Следовательно, выражение А + В * С интерпретируется как А + (В * С). Говорят, что умножение имеет более высокий приоритет, чем сложение.

Предположим, что мы хотим записать выражение А + В * С в постфиксной записи. Учитывая правила приоритетности операций, мы сначала преобразуем часть выражения, которая вычисляется первой – умножение. Выполняя преобразование поэтапно, получим

  1. А + (В * С) – скобки для выделения

  2. А + (В С *) – преобразование операции умножения

  3. А (В С *) + – преобразование операции сложения

  4. А В С * + – постфиксная форма

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

  1. (А + В) * С – инфиксная форма

  2. (А В +) * С – преобразование операции сложения

  3. (А В +) С * – преобразование операции умножения

  4. А В + С * – постфиксная форма

Правила приоритетности для преобразования из инфиксной в префиксную форму аналогичны. Единственное отличие от постфиксного преобразования состоит в том, что операция помещается перед операндами, а не после них.

Примеры выражений в инфиксной, постфиксной и префиксной формах:

Инфиксное представление

Постфиксное представление

Префиксное представление

A + B

A B +

+ A B

A + B – C

A B + C –

– + A B C

(A + B) * (C – D)

A B + C D – *

* + A B – C D

A / B * C – D + E / F / (G + H)

A B / C * D – E F / G H + / +

+ – * / A B C D / E / F + G H

((A + B) * C – (D – E)) * (F + G)

A B + C * D E – – F G + *

* – * + A B C – D E + F G

A – B / (C * (D – E))

A B C D E – * / –

– A / B * C – D E

Алгоритм вычисления выражения, записанного в постфиксной форме:

Каждая операция в постфиксной строке ссылается к предшествующим двум операндам этой строки. Разумеется, одни из этих двух операндов может быть результатом выполнения предыдущей операции. Всякий раз, когда мы прочитываем операнд, мы записываем его в стек. Когда мы достигаем операции, то относящиеся к ней операнды будут двумя верхними элементами стека. Затем можно извлечь эти два операнда, осуществить над ними указанную операцию, и записать результат в стек. Тем самым он станет доступен в качестве операнда применительно к следующей операции.

Примервычисления выражения, заданного в постфиксной форме. Операндами являются цифры от 0 до 9. В программе используется описанный выше тип данныхstack.

#include <iostream.h>

#include <conio.h>

#include "stack.h"

intval(charc);//функция получения значения числа

main()

{

Element * stack;

char str[80];

int i, op1, op2, rez;

MakeNull (stack);

cin>>str;

for (i=0; str[i]; i++)

{

if(str[i]>='0' &&str[i]<='9')//если очередной символ - цифра

Push(val(str[i]),stack);//то она записывается в стек

else//иначе

{

op2 =Top(stack);//операнд2 берется с вершины стека

Pop(stack);//и из стека удаляется

op1 =Top(stack);//операнд 1 тоже берется из стека

Pop(stack);//и тоже из него удаляется

switch(str[i])// в зависимости от символа операции

{//выполняются арифметические действия

case '+' : {rez = op1 + op2; break;}

case '-' : {rez = op1 - op2; break;}

case '*' : {rez = op1 * op2; break;}

case '/' : {rez = op1 / op2; break;}

}

Push(rez,stack);//результат помещается в стек для использования

//его в качестве следующего операнда

}

}

cout<<rez<<'\n';

Pop (stack);//стек очищается

getch();

return 0;

}

int val (char c)

{

return c-48;

}

Соседние файлы в папке Программирование на ЯВУ-Снижко