多位数的后缀评估

时间:2014-03-10 04:39:14

标签: java postfix-notation

我编写了一个后缀评估程序,我能够正确地为单个数字编号。 现在我需要知道如何为多位数字进行操作,因为我当前的程序将两位数的数字评估为不同的数字。

以下是代码:

public class PostfixEvaluation {

    public static void main(String[] args) {
        String postfix = "23+79*-";

        Stack stack = new Stack();

        for (int i = 0; i < postfix.length(); i++) {
            if (postfix.charAt(i) == '+') {
                int v1 = stack.pop();
                int v2 = stack.pop();
                stack.push(v2 + v1);
            } else if (postfix.charAt(i) == '-') {
                int v1 = stack.pop();
                int v2 = stack.pop();
                stack.push(v2 - v1);
            } else if (postfix.charAt(i) == '*') {
                int v1 = stack.pop();
                int v2 = stack.pop();
                stack.push(v2 * v1);
            } else if (postfix.charAt(i) == '/') {
                int v1 = stack.pop();
                int v2 = stack.pop();
                stack.push(v2 / v1);
            } else if (postfix.charAt(i) == '^') {
                int v1 = stack.pop();
                int v2 = stack.pop();
                stack.push((int) Math.pow(v2, v1));
            } else {
                stack.push((int) postfix.charAt(i) - 48);
            }
        }
        System.out.println(stack.pop());
    }

}

4 个答案:

答案 0 :(得分:4)

为了能够识别多位数字,两个数字之间必须有一个分隔符号。

例如,您可以使用空格作为分隔符号。 postfix中的所有标记都将以空格分隔。您的示例将变为"2 3 + 7 9 * -"。您应该一次读取一个令牌,而不是一个角色。

答案 1 :(得分:2)

通过堆栈评估后固定表达式的传统逻辑可以解决仅1位数的数字,即0-9。这是所使用的逻辑的一个非常大的缺点,并且它使得该程序没有实际用途。通过简单地改变输入到堆栈的方法,我们已经消除了单个数字整数的问题,现在可以使用任何数字的数字进行评估。虽然我的代码是用C语言完成的,但你仍然可以使用算法: http://wowmoron.wordpress.com/2014/11/16/evaluation-of-postfix-expression-containing-multi-digit-integer/

答案 2 :(得分:1)

您需要跟踪先前的读数是否为数字。如果是这样,你得到另一个数字,那么你应该从堆栈中弹出值,将其乘以10,添加刚刚读取的数字并将其推回堆栈。您还需要分隔属于不同数字的数字。在大多数RPN计算器上,有一个“Enter”按钮用于此目的。所以选择一个分隔符。

答案 3 :(得分:1)

好吧,这可能不是最佳方法,但无论如何,您必须维护一个 num 变量来存储数字(将逐位添加直到遇到空格);

~我还没有测试边缘情况~ 我的代码如下:

#include <iostream>

#include<cmath>

#include<stack>

#include<string.h>

using namespace std;
int prefixEval(string s) {
  int n = s.length();
  int operand2;
  int operand1;

  stack < int > st;

  for (int i = 0; i <= n - 1; i++) {

    int num = 0, mult = 1, numOfDigits = 0, count = 0;

    if ((s[i] >= '0' && s[i] <= '9') || s[i] == ' ') {
      int j = i;
      while (s[j] != ' ') {
        count++;
        j++;
      }
      mult = pow(10, count - 1);
      while ((s[i] >= '0' && s[i] <= '9') && s[i] != ' ') {

        st.push(s[i] - '0');
        int temp = st.top();
        st.pop();
        num = num + mult * temp;
        mult /= 10;
        i++;
        if (s[i] == ' ') {
          st.push(num);

          break;
        }
      }

    } else {
      int operand2 = st.top();
      st.pop();
      int operand1 = st.top();
      st.pop();
      switch (s[i]) {
      case ('+'):
        st.push(operand1 + operand2);
        break;

      case ('-'):
        st.push(operand1 - operand2);
        break;

      case ('/'):
        st.push(operand1 / operand2);
        break;

      case ('*'):
        st.push(operand1 * operand2);
        break;
      default:
        break;

      }
    }
  }
  return st.top();

}

int main() {
  string s;
  getline(cin, s);

  cout << prefixEval(s);

}