中缀表达式转后缀(逆波兰)表达式

中缀表达式转后缀表达式

多位数求解

直接遍历不需要字符匹配

两次O(n)得出结果,

1.中缀转后缀(后缀便于计算机计算,中缀便于人类理解)

2.后缀算结果

先上思路分析

 这是b站站韩顺平老师的一个思路

当然这个算法是其他人发明的

这个算法记住就行

上我根据思路写的代码

public class PolandNotation {

    Stack<Integer> stack;//操作栈
    private String poland;//表达式

    PolandNotation(String poland){
        transitSuffix(poland);
        System.out.println(this.poland);
        this.stack  = new Stack<>();
        System.out.println(toInfixExpressionList(this.poland));
    }
    public int toInfixExpressionList(String poland){
        //逆波兰表达式求解
        int index = 0;
        while(true)
        {
            if(index>=poland.length())
                break;
            char ch = poland.charAt(index);
            if(ch == ' ')
            {
                //空字符直接跳过
                index++;
                continue;
            }
            if(Character.isDigit(ch))
            {
                //数字字符
                int num = ch-'0';
                if(index<poland.length()-1&&Character.isDigit(poland.charAt(index+1)))
                {
                    //获取多位数
                    while(index<poland.length()-1&&Character.isDigit(poland.charAt(index+1)))
                    {
                        char t = poland.charAt(index+1);
                        num *= 10;
                        num += t-'0';
                        index++;
                    }
                }
                index++;
                stack.push(num);
                continue;
            }
            else if(isOper(ch))
            {
                //操作符
                int num1 = stack.pop();
                int num2 = stack.pop();
                int res = operation(num1,num2,ch);
                stack.push(res);
                index++;
            }
        }
        return stack.pop();
    }
    public String  transitSuffix(String infix){
        //中缀表达式转后缀表达式
        //初始化两个栈
        Stack<Integer> nums = new Stack<>();
        Stack<Integer> opers = new Stack<>();

        int index = 0;
        while(index<infix.length())
        {
            char ch = infix.charAt(index);
            if(ch == ' ')
            {
                index++;
                continue;
            }
            else if(Character.isDigit(ch))//数字
            {
                int num = ch-'0';
                //获取多位数
                while(index<infix.length()-1&&Character.isDigit(infix.charAt(index+1)))
                {
                    char t = infix.charAt(index+1);
                    num *= 10;
                    num += t-'0';
                    index++;
                }
                index++;
                nums.push(num);
            }
            else if(isOper(ch))//操作符
            {
                if(opers.isEmpty()||opers.peek()=='('||priority(ch)>priority(opers.peek()))
                {
                    opers.push((int) ch);
                    index++;
                }
                else
                {
                    nums.push(opers.pop());
                }
            }
            else if(isBracket(ch))//括号
            {
                if(ch == '(')
                {
                    opers.push((int)ch);
                    index++;
                }
                else
                {
                    while(opers.peek() != '(')
                    {
                        nums.push(opers.pop());
                    }
                    opers.pop();
                    index++;
                }
            }
        }
        //栈逆序
        while(!nums.isEmpty())
        {
            opers.push(nums.pop());
        }
        poland = "";
        //栈弹出
        while(!opers.isEmpty())
        {
            if(isOper(opers.peek()))
                poland += ""+toChar(opers.pop());
            else
                poland += ""+opers.pop();
            poland += " ";
        }
        return poland;
    }
    public char toChar(int oper)
    {
        return (char) oper;
    }

    //判断是否为括号
    public boolean isBracket(int bracket){
        return bracket=='('||bracket==')';
    }
    //判断是否是操作符
    public boolean isOper(int oper){
        return oper=='+'||oper=='-'||oper=='*'||oper=='/';
    }
    //操作符赋优先级
    public int priority(int oper){
        if(oper == '*'||oper == '/')
            return 1;
        else if(oper == '+'||oper == '-')
            return 0;
        else
            return -1;
    }
    //运算函数
    public int operation(int num1,int num2,char oper){
        int res = 0;
        switch (oper)
        {
            case '+':
                return num1+num2;
            case '-':
                return num2-num1;
            case '*':
                return num1*num2;
            case '/':
                return num2/num1;
            default:
                break;
        }
        return -1;
    }
}

总体来说就两个函数比较复杂

其他都是一些简单判断与计算

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值