Java 中缀到后缀

Java 中缀到后缀,java,infix-notation,postfix-operator,infix-operator,Java,Infix Notation,Postfix Operator,Infix Operator,我正在尝试将中缀转换为后缀。例如: "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

我正在尝试将中缀转换为后缀。例如: "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();
                }
            }
        }
    }
}
Stack s=新堆栈();
字符串后缀=”;
布尔输入=true;
字符串infixExpr=“20+2*3+(2*8+5)*4”;
对于(int i=0;i空间)
您没有在后缀变量上添加任何空格。您只检查当前字符是否是“有趣”字符之一(数字、运算符),而不是它是否是空格。因此,如果当前字符是空格,您只需跳过它,而不将其复制到后缀

因为你在后缀中放的东西都是你检查过的字符,所以你最终没有空格

您可以这样解决它:

  • 在number
中添加一个名为
的布尔值,首先将其设置为true
  • 无论何时处理一个数字,在将其添加到
    postfix
    之前,请检查
    inNumber
    是否为真。如果为真,请先添加一个空格
  • 如果您刚刚处理了一个数字,请将数字中的
    in设置为true
  • 如果正在处理运算符,请将编号中的
    inNumber
    设置为false
  • 每当向堆栈中添加任何运算符时,请先添加一个空格
  • 数字
    中的
    概念是所有属于同一数字的数字之间不应该有空格。但如果在上一轮处理运算符后将数字添加到后缀
    ,则它属于一个新数字,因此应该有空格

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

            if(Character.isDigit(infixExpr.charAt(i)) == true){
                if ( ! inNumber ) {
                    postfix += " ";
                }
                postfix = postfix + infixExpr.charAt(i);
                inNumber = true;
            }
    
            postfix = postfix + " " + s.pop();
    
    并且在每一个指示运算符的
    if
    中,都应该有
    inNumber=false

    在后缀中添加运算符的每个位置应如下所示:

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

    处理括号 另一个问题是处理
    ()

    首先,您将检查
    的代码放在
    *
    /
    if
    中。当然,如果
    i
    位置的字符是
    *
    //code>,则它不是
    ,因此永远不会调用此代码

    因此,您应该将括号外的
    if
    移动到与数字和运算符上的
    if
    相同的级别

    另外,您使用的
    enter
    是错误的。如果括号内有括号,如
    (3+(5+7))
    ,那么在第一次
    时,您将返回到
    5
    后面的括号,这是可以的。但是,
    enter
    将变为false,您将无法正确处理外部对。这同样适用于
    (3+5)*(7+2)
    ,因为您没有在程序开始后再次将
    enter
    设置为
    true

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


    未映射运算符 最后,当您完成扫描输入时,您将完成扫描。但此时,仍有运算符在堆栈上等待!您必须将它们全部弹出并添加到
    postfix
    。因此,在循环之后,您应该:

        while ( ! s.isEmpty()) {
            postfix += " " + s.pop();
        }
    

    补充说明:

    • 如果使用
      switch
      语句而不是使用所有那些
      if
      语句,则会更好、更清晰
    • 将布尔表达式与
      true
      进行比较是没有意义的。编写
      if(s.isEmpty()==true)
      的正确方法是
      if(s.isEmpty())
      ,而不是
      s.isEmpty()!=true
      使用
      !s.isEmpty()
    • 你没有做任何语法检查。我不确定这是否是因为这是家庭作业,但在现实生活中,你应该检查每个
      )都与
      匹配,每个运算符都有两个操作数,并且还要处理负数,负数开头可能有一个
      -

    问题是您没有添加空格。但是,您不能简单地在每个数字之间添加空格。您必须确保没有在整数的数字之间添加空格。为了解决这个问题,我只需在
    if(infixExpr.charAt(I)='+'.\124; 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 += " ";
    


    这是我给你答案的密码

    #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;
    }
    
    #包括
    #包括
    使用名称空间std;
    布尔高(字符a、字符b)
    {
    如果(b='')
    返回true;
    如果(a==b),则为else
    返回false;
    else如果(a=='/'))
    返回true;
    else if(a='*'&&b!='/'))
    返回true;
    else如果(b=='/'))
    返回false;
    如果(a!='/'&&b=='*'),则为else
    返回false;
    else如果(b='-')
    返回true;
    如果(a='-'&&b!='('),则为else
    返回false;
    else如果(b=='(')
    返回true;
    else如果(a=='(')
    返回true;
    如果(a=='),则为else)
    返回false;
    }
    main()
    {
    int k=0;
    字符串s;
    stacks1;
    s1.推动(“”);
    char ch;
    而(cin>>ch)
    {
    如果(ch=='(')
    {
    k=1;
    s1.推(ch);}
    
    否则,如果(ch>47&&ch)您是否尝试过使用调试器逐步解决此问题?添加一些解释,说明此答案如何帮助解决当前问题,除非它解决了他的问题,否则它不是答案,如果您需要说明原因。