中缀到Postfix

时间:2014-12-16 18:19:39

标签: java infix-notation postfix-operator infix-operator

我正在尝试将中缀转换为postfix。例如:                  " 20 + 2 * 3 +(2 * 8 + 5)* 4" - > 20 2 3 * + 2 8 * 5 + 4 * + 这是我的代码:

Stack<Character> s = new Stack<Character>();
String postfix = "";
boolean enter = true;
String infixExpr = "20 + 2 * 3     + (2*8 + 5)* 4";

for(int i = 0;i<infixExpr.length();i++){

    if(Character.isDigit(infixExpr.charAt(i)) == true){
        postfix = postfix + infixExpr.charAt(i);
    }
    if(infixExpr.charAt(i) == '+' || infixExpr.charAt(i) == '-'){
        if(s.isEmpty() == true){
            s.push(infixExpr.charAt(i));
        }
        else{
            if(s.peek() == '*' || s.peek() == '/' || s.peek() == '+' || s.peek() == '-'){
                while(s.isEmpty()== false){
                    postfix = postfix + s.pop();
                }
                s.push(infixExpr.charAt(i));
            }
            else{
                s.push(infixExpr.charAt(i));
            }
        }
    }
    if(infixExpr.charAt(i) == '*' || infixExpr.charAt(i) == '/' ){
        if(s.isEmpty() == true){
            s.push(infixExpr.charAt(i));
        }
        else{
            if(s.peek()== '+' || s.peek() == '-' || s.peek() == '('){
                s.push(infixExpr.charAt(i));
            }
            else if(s.peek() == '*' || s.peek() == '/'){
                while(s.isEmpty()== false){
                    postfix = postfix + s.pop();
                }
                s.push(infixExpr.charAt(i));
            }
        }
        if(infixExpr.charAt(i) == '('){
            s.push(infixExpr.charAt(i));
        }
        if(infixExpr.charAt(i) == ')'){
            while(enter){

                if(s.peek() == '('){
                    enter = false;
                }
                else{
                    postfix = postfix + s.pop();
                }
            }
        }
    }
}

由于它是在顶部写的,我想得到&#34; 20 2 3 * + 2 8 * 5 + 4 * +&#34;但我得到&#34; 2023 * + 28 * + 54&#34;这是错的,我修改了代码很多次,但我仍然无法看到问题。如果有人能帮忙的话会很棒。

3 个答案:

答案 0 :(得分:2)

空间

您没有在postfix变量上添加任何空格。您只检查当前字符是否是“有趣”字符(数字,运算符)之一,而不是它是否是空格。因此,如果当前字符是空格,您只需跳过它就不会将其复制到后缀。

由于您在后缀中添加的唯一内容是您已检查过的字符,因此最终根本没有空格。

你可以这样解决:

  • 添加一个名为inNumber的布尔值,首先将其设置为true。
  • 每当您处理数字时,在将其添加到postfix之前,请检查inNumber是否为真。如果是这样,请先添加空格。
  • 如果您刚刚处理了一个数字,请将inNumber设置为true。
  • 如果您正在处理运算符,请将inNumber设置为false。
  • 每当您向堆栈添加任何运算符时,请先添加空格。

关于这个inNumber的想法是,所有属于相同数字的数字不应该在它们之间有空格。但是如果在我们在前一轮中处理了一个运算符之后将数字添加到postfix,那么它就属于一个新数字,因此那里应该有一个空格。

基本上,您的数字处理代码应如下所示:

        if(Character.isDigit(infixExpr.charAt(i)) == true){
            if ( ! inNumber ) {
                postfix += " ";
            }
            postfix = postfix + infixExpr.charAt(i);
            inNumber = true;
        }

在表示操作符的每个if中,您应该inNumber = false

每个向postfix添加运算符的地方应如下所示:

        postfix = postfix + " " + s.pop();

处理括号

您的另一个问题是()的处理。

首先,您将检查()的代码放在if*的{​​{1}}内。当然,如果/位置的字符是i*,则它不是/(,因此永远不会调用此代码。

因此,您应将括号外的)移到数字和运算符的if的同一级别。

另外,您对if的使用是错误的。如果括号内有括号,如enter,那么在第一个( 3 + ( 5 + 7 ) ),您将在)之后一直返回括号,这是正常的。但是5将变为false,您将无法正确处理外部对。对于enter也是如此,因为在程序开始后您没有再次将(3 + 5 ) * ( 7 + 2 )设置为enter

不应使用true,而应该弹出堆栈中的内容并检查它是否为enter

(

Unpopped运算符

最后,完成扫描输入后结束。但此时你仍然会有操作员在堆栈上等待!您必须将它们全部弹出并添加到 if(infixExpr.charAt(i) == '('){ inNumber = false; s.push(infixExpr.charAt(i)); } if(infixExpr.charAt(i) == ')'){ inNumber = false; char popped; while ( ( popped = s.pop() ) != '(' ) { postfix = postfix + " " + popped; } } 。所以在循环之后你应该:

postfix

补充说明:

  • 如果不使用所有 while ( ! s.isEmpty()) { postfix += " " + s.pop(); } 语句,那么使用if语句会更好更明确。
  • 将布尔表达式与switch进行比较没有意义。写true的正确方法只是if (s.isEmpty() == true),而不是if (s.isEmpty())使用s.isEmpty() != true
  • 您没有进行任何语法检查。我不确定是不是因为这是家庭作业,但在现实生活中你应该检查每个! s.isEmpty()是否与(相匹配,每个操作员都有两个操作数,并且还处理可能有的负数一开始)

答案 1 :(得分:0)

问题是您没有添加空格。但是,您不能在每个数字之间添加空格。您必须确保没有在整数的数字之间添加空格。要解决此问题,我只需在postfix += " ";之后添加if(infixExpr.charAt(i) == '+' || infixExpr.charAt(i) == '-'),然后在if(infixExpr.charAt(i) == '*' || infixExpr.charAt(i) == '/' )之后再添加20 2 3 *+2 8 *+5 4。这背后的逻辑是,一旦遇到操作员,您就知道操作员之前的所有内容都是数字。现在,当我运行程序时,输出为 if(infixExpr.charAt(i) == '+' || infixExpr.charAt(i) == '-'){ postfix += " "; 。在运算符之间仍然需要添加一些空格,但我会让你处理它。

修改后的代码:

    if(infixExpr.charAt(i) == '*' || infixExpr.charAt(i) == '/' ){
        postfix += " ";

...

{{1}}

答案 2 :(得分:-1)

这是我的答案代码

#include<stack>
#include<iostream>
using namespace std;
bool high(char a,char b)
{
  if(b==' ')
    return true;
  else if(a==b)
    return false;
  else if(a=='/')
    return true;
  else if(a=='*'&&b!='/')
    return true;
  else if(b=='/')
    return false;
  else if(a!='/'&&b=='*')
    return false;
  else if(b=='-')
    return true;
  else if(a=='-'&&b!='(')
    return false;
  else if(b=='(')
    return true;
  else if(a=='(')
    return true;
  else if(a==')')
    return false;
}
main()
{
int k=0;
string s;
stack<char>s1;
s1.push(' ');
char ch;
while(cin>>ch)
{
    if(ch=='(')
    {
    k=1;
    s1.push(ch);}
    else if(ch>47&&ch<58)
    s.push_back(ch);
    else if(high(ch,s1.top()))
    s1.push(ch);
    else if(!high(ch,s1.top())&&ch!=')')
    {
        while(!s1.empty()&&!high(ch,s1.top()))
        {
            s.push_back(s1.top());
            s1.pop();
        }   
    s1.push(ch);}
    else if(ch==')')
    {
        while(!s1.empty()&&s1.top()!='(')
        {
            s.push_back(s1.top());
            s1.pop();
        }
        s1.pop();
        k=0;
    }

}
while(!s1.empty())
{
    s.push_back(s1.top());s1.pop();
}
cout<<s;
}