Java中缀表达式转后缀表达式.

有点不好写,大家可以看看这个思路,当然有多种方法!

package zhan;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

//中缀表达式转后缀表达式
//1+((2+3)*4)-5转换成后缀表达式
//1.因为对String操作不方便,因此先把中缀放到集合里面
//2.将得到的中缀表达式对应的list转换成后缀表达式对应的list
public class ArrayStackTest04 {
    public static void main(String[] args) {
        String s="1+((2+3)*4)-5";
        System.out.println(zhongZhuiList(s));//因为对String操作不方便,因此先把中缀放到集合里面
        System.out.println(houZhuiList(zhongZhuiList(s)));//将得到的中缀表达式对应的list转换成后缀表达式对应的list
        System.out.println(cal(houZhuiList(zhongZhuiList(s))));//计算
    }
    //先将中缀表达式转  换成list集合
    public static List zhongZhuiList(String s){
         List list=new ArrayList<>();
         String str;//用于拼接多位数
        char c;//每遍历到一个字符,就放入到c
        int i=0;//指针,用于遍历中缀表达式
        do {
            //先判定是不是运算符
            if ((c=s.charAt(i))<48||(c=s.charAt(i))>57){
                list.add(c+"");
                i++;
            }else{//是数字,需要考虑多位数
               str="";
               while (i=48&&(c=s.charAt(i))<=57){
                   str+=c;
                   i++;
               }
               list.add(str);
            }
        }while (i houZhuiList(List list){
         //定义两个栈
        Stack s1=new Stack<>();
        //s2这个栈,在整个转换过程中,没有出栈操作,而且后面我们还需要逆序输出,因此用栈比较麻烦,可以直接用集合
        //Stack s2=new Stack<>();
        List s2=new ArrayList<>();

        //遍历中缀表达式集合
        for (String item:list){
            //如果是一个数字,加入到s2
            if (item.matches("\\d+")){
                     s2.add(item);
            }else if (item.equals("(")){
                s1.push(item);
            }else if (item.equals(")")){
                //如果是右括号,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这对括号丢弃
                while (!s1.peek().equals("(")){
                    s2.add(s1.pop());
                }
                s1.pop();//将(弹出s1  消除小括号
            }else {
                //当item的优先级小于等于s1栈顶运算符的优先级时,将s1栈顶的运算符弹出并压入到s2,再转到4.1与s1中新的栈顶运算比较
                while (s1.size()!=0&&Operation.get(s1.peek())>=Operation.get(item)){
                    s2.add(s1.pop());
                }
                //还需要将item压入栈
                s1.push(item);
            }
        }
        //将s1中剩余的运算符依次弹出并加入s2
        while (s1.size()!=0){
            s2.add(s1.pop());
        }
        return s2;
    }
    //完成对逆波兰表达式的运算
    public static int cal(List list){
        //创建只需一个栈
        Stack stack=new Stack<>();
        //遍历list
        for (String p:list) {
            //使用正则表达式来取数
            if (p.matches("\\d+")) {//匹配的是多位数
                stack.push(p);//如果是数字,则入栈,如果是符号则进行运算
            }else {
                int num2=Integer.parseInt(stack.pop());
                int num1=Integer.parseInt(stack.pop());
                int res=0;
                if (p.equals("+")){
                    res=num1+num2;
                }else if (p.equals("-")){
                    res=num1-num2;
                }else if (p.equals("*")){
                    res=num1*num2;
                }else if (p.equals("/")){
                    res=num1/num2;
                }else {
                    throw new RuntimeException("运算符有错误");
                }
                //把计算结果入栈
                stack.push(String.valueOf(res));//或者stack.push(res+"");
            }
        }
        return Integer.parseInt(stack.pop());
    }

}
//编写一个类返回一个运算符对应的优先级
class Operation{
    private static int ADD=1;
    private static int SUB=1;
    private static int MUL=2;
    private static int DIV=2;
    //写一个方法 返回对应的优先级
    public static int get(String operation){
       int result=0;
       switch (operation){
           case "+":
               result= ADD;
               break;
           case "-":
               result= SUB;
               break;
           case "*":
               result= MUL;
               break;
           case "/":
               result=DIV;
               break;
           default:
               result=0;
               break;
       }
       return result;
    }
}

 

你可能感兴趣的:(java,c++,算法)