将Infix表达式转换为Postfix表达式 - 无效的空间插入

时间:2012-05-11 20:41:11

标签: java parsing spacing

我正在创建一个转换器,它将采用中缀表达式并将它们转换为后缀表达式。

Example:
Infix: 2 * 3 - 10 / 4
Postfix: 2 3 * 10 4 / -

我有一个完全编码的方法,但它返回的后缀表达式是

2     3   *   1 0     4 / -

这有两个问题:1。主要问题是它们是1和0之间的空格,当它们应该在一起时(10)。 2.有很多额外的空格,输出应该与上面提供的例子类似。

我已经完成了从中缀转换为后缀的研究,但我无法确定如何进行更多的单位数表达式转换。

下面附有我的postfixtoinfix类,表达式变量保存上面示例中指示的具有完美间距的中缀。

import java.util.*;

public class InfixToPostfix
{
//Declare Instance Variables
private String expression;
private Stack<Character> stack = new Stack<Character>();

//Constructor
public InfixToPostfix(String infixExpression)
{
        expression = infixExpression;
}//End of constructor

//Translate's the expression to postfix
public String translate()
{
    //Declare Method Variables
    String input = "";
    String output = "";
    char character = ' ';
    char nextCharacter = ' ';

    for(int x = 0; x < expression.length(); x++)
    {
        character = expression.charAt(x);

        if(isOperator(character))
        {
            while(!stack.empty() && precedence(stack.peek())>= precedence(character))
                output += stack.pop() + " ";
            stack.push(character);
        }   
        else if(character == '(')
        {
            stack.push(character);
        }
        else if(character == ')')
        {
            while(!stack.peek().equals('('))
                output += stack.pop() + " ";
            stack.pop();
        }
        else
        {
            if(Character.isDigit(character) && (x + 1) < expression.length() && Character.isDigit(expression.charAt(x+1)))
            {
                output += character;
            }
            else if(Character.isDigit(character))
            {
                output += character + " ";
            }   
            else
            {
                output += character;
            }
        }
    }//End of for

    while(!stack.empty())
    {
        output += stack.pop() + " ";
    }

    return output;
}//End of translate method

//Check priority on characters
public static int precedence(char operator)
{
    if(operator == '+' || operator =='-')
        return 1;
    else if(operator == '*' || operator == '/')
        return 2;
    else
        return 0;
}//End of priority method

public boolean isOperator(char element)
{
    if(element == '*' || element == '-' || element == '/' || element == '+')
        return true;
    else
        return false;
}//End of isOperator method

}//End of class

3 个答案:

答案 0 :(得分:2)

您的代码并未将“10”视为单个实体,而是将两个单独的字符“1”和“0”视为“0”。对于任何不是运算符或parens的内容,您执行的output += character + " ";将为您提供1 0而不是所需的10

答案 1 :(得分:0)

将任意算术表达式从其中缀(即传统的算术表达式)转换为后缀形式的问题并不像最初看起来那么简单。

算术表达式表示无上下文语言,可以使用下推自动化识别。作为这种识别的结果,可以构造语法树或AST(抽象语法树),其将自下而上地行走以构造后缀形式。

关于这一点的一本很好的实用书,没有太多的理论是Language Implementation Patterns,我强烈推荐。

答案 2 :(得分:0)

就像@digitaljoel所说的那样,你将单个字符识别为词汇标记,而不是完整的单词作为标记。

您应该让解析器调用一个方法从输入中读取下一个完整的标记,而不是读取单个字符然后决定它是什么标记(操作符或操作数)。然后,令牌可以作为字符串(包含一个或多个包含令牌的字符)返回,或作为类对象(包含令牌的文本和某种token_type属性)返回。

否则,您的解析器仅限于处理单字符令牌。

使用单独的词法分析器来读取令牌的另一个好处是你可以在词法分析器而不是解析器中处理空格。