- •Министерство образования и науки рф
- •2. Определение
- •3. Описание
- •4. Вычисления на стеке
- •4.1. Общий порядок
- •4.2. Пример вычисления выражений
- •5. Преобразование из инфиксной нотации
- •5.1. Простой пример
- •5.2. Алгоритм
- •5.3. Сложный пример
- •6. Оптимизация выражений
- •6.1. Пример алгоритма упрощения выражения
- •6.2. Пример работы алгоритма
- •7. Примеры реализации
- •8. Практические реализации
- •Список литературы:
6. Оптимизация выражений
Если вы пишете интерпретатор, то выходная строка, полученная после преобразования исходного выражения в обратную польскую нотацию, может храниться вместо исходного выражения для последующей интерпретации. Обратная польская нотация также позволяет компьютеру упрощать выражения.
6.1. Пример алгоритма упрощения выражения
Рассмотрим алгоритм, который осуществляет предвычисление констант в выражении. Дано выражение в ОПН. Нам понадобится стек для хранения смешанных данных (чисел и операторов).
Алгоритм подобен тому, который применяется для вычисления выражений. Мы просматриваем выражение слева направо.
Пока есть символы для чтения:
Читаем очередной символ.
Если символ является числом, помещаем его в стек.
Если символ является переменной, считая что переменная имеет значение null, помещаем символ в стек.
Если символ является оператором:
1) (если все аргументы оператора, лежащие в стеке, имеют значение, отличное от null) выталкиваем аргументы оператора из стека и помещаем в стек результат операции;
2) (если хотя бы один из аргументов имеет значение null) считая что результат операции null, кладём символ оператора в стек.
После того, как всё выражение просмотрено, то, что осталось в стеке, является оптимизированым выражением (операторы выражения лежат в стеке в обратном порядке).
6.2. Пример работы алгоритма
Выражение
Инфиксая нотация: exp(-1/2*x)
Обратная Польская нотация: -1 2 / x * exp
Читаем: «-1»
Кладём «-1» в стек
Стек: -1
Читаем: «2»
Кладём «2» в стек
Стек: -1 2
Читаем: «/»
Вычисляем частное, результат кладём в стек
Стек: -0.5
Читаем: «x»
Кладём «x» в стек со значением null
Стек: -0.5 x(null)
Читаем: «*»
Кладём «*» в стек со значением null
Стек: -0.5 x(null) *(null)
Читаем «exp»
Кладём «exp» в стек со значением null
Стек: -0.5 x(null) *(null) exp(null)
Результат оптимизации: -0.5 x * exp
Данный метод, очевидно, не включает всех возможных способов оптимизации.
7. Примеры реализации
#include <string.h>
int main(void)
{
float stack[70];
float res;
int m = 0;
char query[100];
printf("Введите выражение: ");
gets(query);
for (int i = 0; i < strlen(query); i++)
{
if (query[i] >= '0' && query[i] <= '9')
{
stack[m] = query[i] - '0';
m++;
continue;
}
switch (query[i])
{
case '+':
{
res = stack[m - 2] + stack[m - 1];
break;
}
case '-':
{
res = stack[m - 2] - stack[m - 1];
break;
}
case '*':
{
res = stack[m - 2] * stack[m - 1];
break;
}
case '/':
{
res = stack[m - 2] / stack[m - 1];
break;
}
}
stack[m - 2] = res;
m--;
}
printf("Ответ: %f", res);
getchar();
return 0;
}