Расчет в польской нотации

У меня есть этот код:

#include <iostream>
#include <string>
#include “stack.h”
int main (int argc, char *argv[]) {
   char *a = argv[1]; 
   int N = strlen(a);
   stack<int> polish(N); int el;
   for (int i = 0; i < N; i++){
      if (a[i] == '+'){
         el = polish.readStack(); polish.outofStack();
         polish.inStack( el + polish.readStack()); polish.outofStack()
      }
      if (a[i] == '*'){
         el = polish.readStack(); polish.outofStack();
         polish.inStack(el * polish.readStack()); polish.outofStack()
      }
      if ((a[i] >= '0') && (a[i] <= '9')){
         el = polish.readStack(); polish.outofStack()
         polish.inStack(10 * el + (a[i++]-'0'));
      }
   }
   cout << polish.outofStack() << endl;
}

Как это работает? И что означает эта строчка?

polish.inStack(10 * el + (a[i++]-'0'));

person m r    schedule 03.07.2015    source источник
comment
Такая странная реализация stack. Общеизвестной практикой является вызов методов push и pop, но не readStack и inStack. Кроме того, pop должен автоматически удалять последний элемент без вызова outOfStack.   -  person Yeldar Kurmangaliyev    schedule 03.07.2015
comment
Поправьте меня, если я ошибаюсь, но это не должно работать: результат операций, которые мы помещаем в стек (без удаления второго операнда), а затем отбрасываем?!   -  person Daniel Jour    schedule 03.07.2015
comment
polish.inStack(10 * el + (a[i++]-'0')); если вы предполагаете, что stack<int>::readStack() возвращает int, это будет означать, что вы передаете 10 * результат этого вызова + следующий символ, который был задан в качестве входных данных для stack<int>::inStack();   -  person Floris Velleman    schedule 03.07.2015
comment
@YeldarKurmangaliyev Похоже на стандартный интерфейс с нестандартными именами - inStack это push, readStack это top, outOfStack это pop.   -  person molbdnilo    schedule 03.07.2015


Ответы (1)


Похоже, это алгоритм, который считывает и вычисляет обратную (постфиксную) польскую нотацию< /а>.

Например,

1 2 3 + 4 - -

означает

Add 1; add 2; add 3; sum up the last two; add 4; substract the last two; substract the last two.

i.e.

1 - ((2 + 3) - 4) = 0

Эта строка кода:

polish.inStack(10 * el + (a[i++]-'0'));

предполагается объединять числа путем добавления цифр.
(a[i++]-'0') преобразует символьную цифру, например «3», в целое число 3.

Изначально у нас в стеке ноль. Например, если у вас есть «123», он будет читать их символ за символом следующим образом:

  1. читать 1. Получить последнее число из стека (0), сделать 0 * 10 + 1 = 1. Поместить его обратно в стек

  2. читать 2. Получить последнее число из стека (1), сделать 1 * 10 + 2 = 12. Вставить его обратно

  3. читать 3. Получите последнее число из стека (12), сделайте 12 * 10 + 3 = 123. Задвиньте его обратно.

  4. Большой! 123 номер прочитан.

Тем не менее, этот пример кода представляет собой кучу плохих практик.

  1. Общеизвестной практикой является называть функции стека Pop и Push, но не readStack() и inStack().
  2. Структура стека требует удаления элемента после чтения. readStack() не предоставляет.
  3. Несколько операторов if вместо switch.
  4. Никогда не увеличивайте счетчик внутри цикла.
  5. Этот код на самом деле не работает, потому что он не разделяет значения.
person Yeldar Kurmangaliyev    schedule 03.07.2015
comment
Часто также peek делает то же, что и readStack. - person Daniel Jour; 03.07.2015