Java计算器实现(逆波兰式)

package hfw.util;


import java.util.ArrayDeque;
import java.util.Deque;


/**
 * 
 *逆波兰式
 *总结,java版的Eval:逆波兰和动态编译,推荐用动态编译,因为逆波兰式不认识"- 4",只认识"-4",且动态编译简单不会出错,且动态编译可以执行任何语句
 *@author hfw20170510
 */
public class RNP {
/**
* 运算数
*/
private static Deque<String> operationNum = new ArrayDeque<String>();
/**
* 运算符
*/
private static Deque<String> operator = new ArrayDeque<String>();
/**
* 将表达式转换为逆波兰式
* @param expression
* @return
*/
private static void str2Rnp(String expression){
operationNum.clear();
operator.clear();
int index = 0;
for(int i=0;i<expression.length();i++){
char c  = expression.charAt(i);
if(isOperator(c) || c=='(' || c==')'){
//操作数直接入栈
String operationNum = expression.substring(index,i);
//区分负号和减号,如果'-'前面的一个是+-*/( 认为是负号,'-'前面的是数或)认为是减号
if(c=='-'){
int in = i;
while((expression.charAt(in-1)) ==' '){
in--;
if(in==0){
break;
}
}
if(in==0){
continue;
}
String previous = expression.substring(in-1,i);
if(isOperator(previous.charAt(0)) || previous.charAt(0)=='('){
continue;
}
}
if(operationNum.trim().length()>0){
RNP.operationNum.push(operationNum.trim());
}
index = i+1;
String operator = c+"";
//如果操作符是'(',直接入栈
if('('==c){
RNP.operator.push(operator);
//如果操作符是')',将'('操作符之后的全部出栈,入栈操作数,'(' ')'舍弃
}else if(')'==c){
while(true){
String o = RNP.operator.pollFirst();
if(o==null || "(".equals(o)){
break;
}
RNP.operationNum.push(o);
}
//如果操作符是+-*/
}else{
String o = RNP.operator.peekFirst();
if(o== null){//如果操作符栈为空,操作符直接入栈
RNP.operator.push(operator);
}else {
char operator2 = o.charAt(0);
//比较操作符,和操作符栈首 的大小,如果操作符大,直接入栈
if(operator2=='(' || operator2==')' || orderOperator(c,operator2)){
RNP.operator.push(operator);
//如果操作符栈首大,将操作符栈小于操作符的全部出栈,入栈操作数,最后改操作符入栈
}else{
while(true){
if(o==null || o.charAt(0) =='('|| o.charAt(0) ==')'){
break;
}
if(orderOperator(c, o.charAt(0))){
break;
}
o = RNP.operator.pollFirst();
RNP.operationNum.push(o);
o = RNP.operator.peekFirst();
}
RNP.operator.push(operator);
}
}
}
}
}
String operationNum = expression.substring(index);
if(operationNum.trim().length()>0){
RNP.operationNum.push(operationNum.trim());
}
while(RNP.operator.size()>0){
RNP.operationNum.push(RNP.operator.pollFirst());
}
// RNP.operationNum.addAll(RNP.operator);
}
//判断一个字符是否为运算符  
    private static boolean isOperator(char c) {  
        return c=='+' || c=='-' || c=='*' || c=='/';
    }  
    //判断运算符顺序,true表示运算符operator1>operator2,false表示相等或小于
    private static boolean orderOperator(char operator1, char operator2){
    if((operator1=='*' || operator1=='/') && (operator2=='+' || operator2=='-')){
    return true;
    }
    return false;
    }
/**
* 计算逆波兰式的值
* @return
*/
    private static double countRnp(){
while(RNP.operationNum.size()>0){
String s = RNP.operationNum.pollLast();
//如果是操作符,取出栈顶的两个操作数,直接运算
char operator = s.charAt(0);
if(s.length()==1 && isOperator(operator)){
String a = RNP.operator.pollFirst();
String b = RNP.operator.pollFirst();
if('+'==operator){
double result =  Double.parseDouble(b)+Double.parseDouble(a);
RNP.operator.push(result+"");
}else if('-'==operator){
double result =  Double.parseDouble(b)-Double.parseDouble(a);
RNP.operator.push(result+"");
}if('*'==operator){
double result =  Double.parseDouble(b)*Double.parseDouble(a);
RNP.operator.push(result+"");
}if('/'==operator){
double result =  Double.parseDouble(b)/Double.parseDouble(a);
RNP.operator.push(result+"");
}
//如果是操作数,入栈
}else{
RNP.operator.push(s);
}
}
double result = Double.parseDouble(RNP.operator.pollLast());
return result;
}
/**
* 计算逆波兰式的值(整数)
* @return
*/
    private static int intRnp(){
while(RNP.operationNum.size()>0){
String s = RNP.operationNum.pollLast();
//如果是操作符,取出栈顶的两个操作数,直接运算
char operator = s.charAt(0);
if(s.length()==1 && isOperator(operator)){
String a = RNP.operator.pollFirst();
String b = RNP.operator.pollFirst();
if('+'==operator){
int result =  Integer.parseInt(b)+Integer.parseInt(a);
RNP.operator.push(result+"");
}else if('-'==operator){
int result =  Integer.parseInt(b)-Integer.parseInt(a);
RNP.operator.push(result+"");
}if('*'==operator){
int result =  Integer.parseInt(b)*Integer.parseInt(a);
RNP.operator.push(result+"");
}if('/'==operator){
int result =  Integer.parseInt(b)/Integer.parseInt(a);
RNP.operator.push(result+"");
}
//如果是操作数,入栈
}else{
RNP.operator.push(s);
}
}
int result = Integer.parseInt(RNP.operator.pollLast());
return result;
}
/**
* 计算表达式的值
* @param expression
* @return
*/
public static double calculate(String expression){
try{
str2Rnp(expression);
return countRnp();
}catch(Exception  e){
e.printStackTrace();
System.out.println("请检查表达式");
return 0.0;
}
}
/**
* 计算表达式的值(整数)
* @param expression
* @return
*/
public static int intCalculate(String expression){
try{
str2Rnp(expression);
return intRnp();
}catch(Exception e){
e.printStackTrace();
System.out.println("请检查表达式");
return 0;
}
}

public static void main(String[] args) {
String s= "53.12* 6/ ( -12-7.2)* -6 *( -4)*12*6/7.2-6";
System.out.println(RNP.calculate(s));
s = "((( -1+ 2 ) *  -2) *  -4)-9*( -1 + 2)";
System.out.println(RNP.intCalculate(s));
}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值