java 实现逆波兰计算器

package com.czp;

import java.util.HashMap;
import java.util.Stack;

public class Calculator {

	//运算符优先级
	private static HashMap<String,Integer> opLs;
	
	private String src;

	public Calculator(String src) {
		this.src = src;
		if(opLs==null)
		{
			opLs = new HashMap<String,Integer>(6);
			opLs.put("+",0);
			opLs.put("-",0);
			opLs.put("*",1);
			opLs.put("/",1);
			opLs.put("%",1);
			opLs.put(")",2);
		}
	}

	//将中缀表达式转化为后缀表达式
	public String toRpn()
	{
		String[] tmp = split(src);
		// 后缀栈
		Stack<String> rpn = new Stack<String>();
		// 临时栈
		Stack<String> tmpSta = new Stack<String>();

		for (String str : tmp) {
			if (isNum(str)) {
				//是操作数,直接压入结果栈
				rpn.push('('+str+')');
			}else{
				//是操作符号
				if(tmpSta.isEmpty())
				{//还没有符号
					tmpSta.push(str);
				}else{
				 //判读当前符号和临时栈栈顶符号的优先级
					if(isHigh(tmpSta.peek(),str))
					{
						if(!str.equals(")"))
						{
							do{
								//1在临时栈中找出小于当前优先级的操作符
								//2压入当前读入操作符
								rpn.push(tmpSta.peek());
								tmpSta.pop();
							}while(!tmpSta.isEmpty()&&(isHigh(tmpSta.peek(),str)));
							
							tmpSta.push(str);
						}else{
							//是)依次弹出临时栈的数据,直到(为止
							while(!tmpSta.isEmpty()&&!tmpSta.peek().equals("("))
							{
								rpn.push(tmpSta.pop());
							}
							if((!tmpSta.empty())&&(tmpSta.peek().equals("(")))
							{//弹出(
								tmpSta.pop();
							}
						}
					}else if(!isHigh(tmpSta.peek(),str)){
						tmpSta.push(str);
					}
				}
			}

		}
		while(!tmpSta.empty())
		{//把栈中剩余的操作符依次弹出
			rpn.push(tmpSta.pop());
		}
		StringBuilder st = new StringBuilder();
		for (String str : rpn) {
        		st.append(str);
		}
		rpn.clear();
		return st.toString();
	}

	//分割(56+4)3*6+2=>(,56,+,4,
	private String[] split(String src) {
		StringBuilder sb = new StringBuilder(src.length());
		for(char ch:src.toCharArray())
		{
			if(ch=='+'||ch=='-'||ch=='*'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='%')
			{
				sb.append(",");
				sb.append(ch);
				sb.append(",");
			}else{
				sb.append(ch);
			}
		}
		String string = sb.toString().replaceAll(",{2,}", ",");
		return string.split(",");
	}

	//比较操作符的优先级
	private boolean isHigh(String pop, String str) {
		if(str.equals(")"))
			return true;
		if(opLs.get(pop)==null||opLs.get(str)==null)
		  return false;
		return opLs.get(pop)>=opLs.get(str);
			
	}

	//是否是数字
	public boolean isNum(String str) {
		for (char ch : str.toCharArray()) {
			if(ch=='+'||ch=='-'||ch=='*'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch=='%')
				return false;
		}
		return true;
	}

	//得到结果
	public double getRes() {
		String rpn = toRpn();
		Stack<Double> res = new Stack<Double>();
		StringBuilder sb = new StringBuilder();
		for(char ch:rpn.toCharArray())
		{ 
			if(ch=='(')
			{
				continue;
			}else if(ch>='0'&&ch<='9'||ch=='.'){
				sb.append(ch);
			}else if(ch==')')
			{
				res.push(Double.valueOf(sb.toString()));
				sb = new StringBuilder();
			}else{
				 if(!res.empty())
				 {
					 Double x = res.pop();
					 Double y = res.pop();
					 switch (ch) {
					case '+':
						 res.push(y+x); 
						break;
					case '-':
						res.push(y-x); 
						break;
					case '*':
						res.push(y*x); 
						break;	
					case '%':
					case '/':	
						if(x!=0)
						{
							double rsd = ch=='%'?y%x:y/x;
							res.push(rsd); 
						}else{
							 System.out.println("分母为零");
							 res.clear();
							 return -1;
						}
						break;
					}
			}
			}
		}
		Double result = res.pop();
		res.clear();
		return result;
	}

	public static void main(String[] args) {
		String src2 = "156899+5*(36+5)-8%3";
		Calculator analyer = new Calculator(src2);
		System.out.println(src2+"="+analyer.getRes());
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值