表达式求值

对表达式求值时分为三步:

  1. 将中缀表达式转换为List,方便遍历
  2. 将中缀表达式的List转化为后缀表达式的List
  3. 计算后缀表达式表示的List的值

运行结果如下

在这里插入图片描述

  1. 将中缀表达式字符串转为List,方便后面遍历
public static List<String> getInfixArrayList(String s){
		//中缀字符串转为list
		List<String> arrayList = new ArrayList<String>();
		int i = 0;// 用于扫描字符串
		String temp = "";
		s = s.replaceAll(" ", "");
		while(i < s.length()){
			if((s.charAt(i) < 48 || s.charAt(i) > 57) && s.charAt(i) != 46) {//不是数字且不是.
				arrayList.add(""+s.charAt(i++));
			}else {
				temp = "";
				while(i < s.length() && (s.charAt(i) == 46 || (s.charAt(i) >= 48 && s.charAt(i) <= 57))) {
					temp += s.charAt(i++);
				}
				arrayList.add(temp);
			}
		}
		return arrayList;
	}
  1. 将中缀表达式的List转为后缀表达式的List
public static List<String> getSuffixArrayList(List<String> infixList){
		//中缀List转后缀List
		List<String> s2 = new ArrayList<String>();	//中间栈s2用list替换
		Stack<String> s1 = new Stack<String>();		//符号栈s1
		for(String item : infixList) {
			if(item.matches("\\d+.{0,1}\\d*")) {//是数字入s2
				s2.add(item);
			}else {
				if("(".equals(item) || s1.size() == 0 || "(".equals(s1.peek())){
					s1.push(item);
				}else if(")".endsWith(item)) {//遇到右括号
					while(s1.size() > 0 && !s1.peek().equals("(")) {
						s2.add(s1.pop());
					}
					s1.pop();//弹出"(" 丢弃一对括号
				}else {//是符号就比较优先级
					while(s1.size() > 0 && priority(item) <= priority(s1.peek())) {
						s2.add(s1.pop());
					}
					s1.push(item);
				}
			}
		}
		while(s1.size() > 0) {
			s2.add(s1.pop());
		}
		return s2;
	}
  1. 对后缀表达式的List求值
public static double clacu(List<String> suffixList) {
		//后缀list求值
		double res = 0;
		Stack<String> stack = new Stack<String>();
		for(String item : suffixList) {
			if(item.matches("\\d+.{0,1}\\d*")) {//如果是多位数
				stack.push(item);
			}else {
				double n1 = Double.parseDouble(stack.pop());
				double n2 = Double.parseDouble(stack.pop());
				if(item.equals("-")) {
					res = n2 - n1;
				}else if(item.equals("+")) {
					res = n2 + n1;
				}else if(item.equals("*")) {
					res = n2 * n1;
				}else if(item.equals("/")) {
					res = n2 / n1;
				}else {
					throw new RuntimeException("找不到符号~");
				}
				stack.push(""+res);
			}
		}
		return res;
	}
	public static int priority(String c) {
		//返回符号的优先级,数字越大优先级越高
		int ADD = 1;
//		int SUB = 1;
		int MUL = 2;
//		int DIV = 2;
		if("+".equals(c) || "-".equals(c)) return ADD;
		else if("*".equals(c) || "/".equals(c)) return MUL;
		else return 0;
	}
  1. 测试程序
public static void main(String[] args) {
		String str = "1.2 + ((2 + 3) * 4) - 5";
		System.out.println("原表达式:"+str);
		List<String> infixlist = getInfixArrayList(str);//将中缀表达式转为List方便遍历
		System.out.println("中缀List:"+infixlist);
		List<String> Suffixlist = getSuffixArrayList(infixlist);//将中缀List转为后缀List
		System.out.println("后缀List:"+Suffixlist);
		double result = clacu(Suffixlist);//对后缀List求值
		System.out.printf("%s = %.2f\n",str,result);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值