逆波兰问题_学习记录

逆波兰问题_学习记录

package p19;

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

/**
 * 逆波兰表达式求值
 * @author Guozhu Zhu
 * @date 2018/8/5
 * @version 1.0
 *
 */
public class NBL {
	
    private static MyStack ms1 = new MyStack();//生成逆波兰表达式的栈
    private static MyStack ms2 = new MyStack();//运算栈

    // 将字符串转换为中序表达式
    public static List<String> zb(String s) {
        List<String> ls = new ArrayList<String>();//存储中序表达式
        int i = 0;
        String str;
        char c;
        while (i < s.length()){
            if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) {
                ls.add("" + c);
                i++;
            } else {
                str = "";
                while (i < s.length() && (c = s.charAt(i)) >= 48
                        && (c = s.charAt(i)) <= 57) {
                    str += c;
                    i++;
                }
                ls.add(str);
            }
        }
        return ls;
    }
    
    //将中序表达式转换为逆波兰表达式
    /**
	1、从左至右扫描中缀表达式。
	2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
	3、若读取的是运算符
	  (1) 该运算符为左括号"(",则直接存入运算符堆栈。
	  (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
	  (3) 该运算符为非括号运算符:
	      (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
	      (b) 若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。
	      (c) 若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
	4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
     */
    public static List<String> parse(List<String> ls) {
        List<String> lss = new ArrayList<String>();
        for (String ss : ls) {
            if (ss.matches("\\d+") || (ss.charAt(0) == '-' && ss.length() > 1)) {        //数字
                lss.add(ss);
            } else if (ss.equals("(")) {     //(
                ms1.push(ss);
            } else if (ss.equals(")")) {     //)
                while (!ms1.top.equals("(")) {
                    lss.add(ms1.pop());
                }
                ms1.pop();       
            } else {
                while (ms1.size() != 0 && getValue(ms1.top) >= getValue(ss)) {
                    lss.add(ms1.pop());
                }
                ms1.push(ss);
            }
        }
        while (ms1.size() != 0) {
            lss.add(ms1.pop());
        }
        return lss;
    }
    
    //对逆波兰表达式进行求值
    public static int jisuan(List<String> ls) {
        for (String s : ls) {
        	//自然数和负数时
            if (s.matches("\\d+") || (s.length() > 1 && s.charAt(0) == 0)) { 
                ms2.push(s);
            } else {
                int b = Integer.parseInt(ms2.pop());
                int a = Integer.parseInt(ms2.pop());
                if (s.equals("+")) {
                    a = a + b;
                } else if (s.equals("-")) {
                    a = a - b;
                } else if (s.equals("*")) {
                    a = a * b;
                } else if (s.equals("\\")) {
                    a = a / b;
                }
                ms2.push("" + a);
            }
        }
        return Integer.parseInt(ms2.pop());
    }
    
    //获取运算符优先级 +,-为1 *,/为2 ()为0
    public static int getValue(String s) {
        if (s.equals("+")) {
        	return 1;
        } else if (s.equals("-")) {
        	return 1;
        } else if (s.equals("*")) {
        	return 2;
        } else if (s.equals("\\")) {
        	return 2;
        }
        return 0;
    }
    
    //========Test========
    public static void main(String[] args) {
        System.out.println(jisuan(parse(zb("1+((2+3)*4)-5"))));
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_37770023/article/details/81433524
今日推荐