java语言中缀表达式转后缀表达式

仅用于 + - * / ( ) 的中缀表达式

思路:
因为在输入表达式的时候,表达式是字符串。为例遍历字符串方便,可以考虑将其转化成为ArrayList类型的。由于表达式中可能会出现多位数的情况(比如20*3,遍历的时候先遍历2再遍历0,但是20才是一个数),所以定义一个变量numString用来拼接数字。所以代码如下:

public static List<String> infixToList(String s){
        List<String> list = new ArrayList<>();
        int index = 0; //字符串的索引
        String numString;//这里是用来拼接数字的
        char ch;// 记录当前遍历到的字符
        do {
            if ((ch = s.charAt(index))=='+'
                    ||(ch = s.charAt(index))=='-'
                    ||(ch = s.charAt(index))=='*'
                    ||(ch = s.charAt(index))=='/'
                    ||(ch = s.charAt(index))=='('
                    ||(ch = s.charAt(index))==')'){
                list.add(""+ch);//如果遍历到的字符是操作符,直接加入到list中
                index++;
            }else{
            //如果遍历到的字符是数,还需要先看他的后一位是不是数      
                numString = "";
                //如果是数,则需要拼接
                while (index<s.length()&&((ch = s.charAt(index))>=48 && (ch = s.charAt(index))<= 57)){
                    numString += ch;
                    index++;
                }
                //否则直接加入到list中
                list.add(numString);
            }
        }while (index<s.length());
        //最后返回list
        return list;
    }

转化为ArrayList之后,就可以很方便的遍历了。现在将其转化为后缀表达式。
step 1:我们需要先初始化一个栈s1,一个数组列表s2(为什么是ArrayList最后再解释)
step 2:从头至尾遍历中缀表达式转化的list
step 3:如果遍历到的是一个数,就直接加入到s2;
step 4:如果遍历到的是括号,其中,如果是“(”,入栈s1;如果是“)”,将s1栈顶运算符依次出栈,但是要加入到s2,直到栈顶元素遇到“(”,就将这一对括号丢弃。
step 5:如果遇到的是运算符(±*/),则比较它与s1栈顶元素的优先级。(5.1)如果s1为空,或者栈顶元素为“(”,则直接将运算符入栈;(5.2)如果不满足条件5.1,且运算符的优先级高于栈顶运算符的优先级,也直接将运算符入栈;(5.3)如果不满足5.1和5.2,则先将栈顶运算符出栈并加入到s2中,再转到5.1与新的栈顶元素继续比较。
step 6:重复步骤step 2~5,直到遍历到表达式的最右边即list的最后一个元素
step 7:将s1的运算符依次出栈,并加入到s2中。
step 8:此时s2中的顺序就是后缀表达式的顺序。为什么不用栈来做s2?因为可以发现,在这个过程中,s2并没有删除元素的操作。且,使用ArrayList的话,s2现在的顺序就是后缀表达式的顺序;如果使用栈(先进后出),还得出栈并且正确的后缀表达式,正好与出栈顺序是相反的。直接用ArrayList更加方便。

代码如下:
(1)中缀转后缀(均为ArrayList类型)

public static List<String> infixToSuffix(List<String> infixList){
        Stack<String> s1 = new Stack<>();
        List<String> s2 = new ArrayList<>();

        for (String s : infixList) {//遍历中缀的list
            if (s.matches("\\d+")){//采用正则表达式判断是否为一个数
                s2.add(s);
            }else if (s.equals("(")){
                s1.push(s);
            }else if (s.equals(")")){        
            	//这里也是peek()不是pop()
                while (!s1.peek().equals("(")){
                    s2.add(s1.pop());
                }
                s1.pop();
            }else {
            	//s1非空,比较运算符与栈顶元素的优先级
            	//这里一定要用peek()方法而不是pop()
                while (s1.size() != 0 && Priority.priority(s) <= Priority.priority(s1.peek())){
                    s2.add(s1.pop());
                }
                s1.push(s);
            }
        }
        //遍历结束,直接将s1的元素出栈加入到s2中
        while (s1.size()!=0){
            s2.add(s1.pop());
        }

        return s2;

    }

比较优先级的代码

public class Priority {
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    public static int priority(String s){
        int result = 0;
        switch (s){
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
                break;
            case "*":
                result = MUL;
                break;
            case "/":
                result = DIV;
                break;
            default:
                break;
        }
        return result;
    }

}

注:这个是学习笔记。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值