Java实现简单四则运算

工作之余,突然想用java实现一下四则运算,经过简单的构思,很快就有了思路,就完成了一个简单版本。

 

经过慎重考虑,觉得使用栈还是要比数组或者List容易对符号和数字进行控制。

我使用两个栈,分别保存数字和符号,然后判断当前符号和前一个符号的运算级别,来决定是否进行一次弹栈运算(就是挨着前一个运算符号的两个数,是不是有必要进行一次运算)。

经过简单的测试,标准的四则运算,在下面代码是没有问题的。

如果再加括号,那就是在这个基础上,添加去括号的流程就可以,等那天有时间了,再完善吧。

 

所有源码如下:

package com.rq.spring.main;




import java.util.Stack;
/**
 * 使用栈完成的简单四则运算,不带有任何括号
 * 测试时,请输入标准的四则运算式
 * 待优化的地方很多,各位大神,多提意见
 * @author 任强
 *
 */
public class TestStackSimpleOperation {


    public static void main(String[] args) {
		//简单语法
		// Stack<String> stack = new Stack<>();//创建一个栈,字符串类型
		// 
		// stack.push("a");//压栈
		// stack.push("b");
		// stack.push("c");
		// 
		// while(!stack.empty()){//判断是否为空
		// String s = stack.pop();//弹栈
		// System.out.println(s);
		// }
		//另一种遍历栈的方法
		// Iterator<String> it = stack.iterator();
		// while(it.hasNext()){
		// String s = it.next();
		// System.out.println(s);
		// }
		//测试自己编写的方法
		// System.out.println(simpleOperation("1+2+3*5+4*6-7/7+1"));//42
		// System.out.println(simpleOperation("1*2*3*4*5*6+1+2*5+9*6+9"));//794
		// System.out.println(simpleOperation("5+6/3*8-9+45*67+95/5+8-85"));//2969
		System.out.println(simpleOperation("1+2+3-4+5*6-7+8-9*6/2/1+99/33*55-951"));//-780
	}
	/**
	* 简单四则运算
	* @param equation 四则运算式
	* @return 运算结果
	*/
	public static int simpleOperation(String equation){
		Stack<Integer> nums = new Stack<>();//保存运算数字的栈
		Stack<String> symbols = new Stack<>();//保存运算符号的栈
		while(equation != null && equation.length() > 0){
			int symIndex = getLastIndex(equation);
			if(symIndex == -1){//表示已经到了运算式的结尾,需要返回结果了
                int num = Integer.valueOf(equation);
				int r = getResult(num, symbols.pop(), nums.pop());
				while(!symbols.empty()) {
					r = getResult(r, symbols.pop(), nums.pop());
				}
				return r;
			}
			int num = Integer.valueOf(equation.substring(0, symIndex));
			nums.push(num);
			String sym = equation.substring(symIndex, symIndex + 1);
			//完成计算流程
			String lastSym = symbols.empty() ? null : symbols.peek();//获取前一个运算符
			//前一个运算符存在,且它的等级是不小于当前运算符,就进行一次运算,
			//把数字栈中的后两个元素弹栈操作,使用前一个运算符完成计算
			//使用while的原因是可能在符号栈中需要继续进行往前一步的运算
			while(lastSym != null && getLevel(lastSym) >= getLevel(sym)){
				nums.push(getResult(nums.pop(), symbols.pop(), nums.pop()));
				lastSym = symbols.empty() ? null : symbols.peek();
			}
			symbols.push(sym);
			equation = equation.substring(symIndex + 1);
		}
		return 0;
	}
	//计算结果,因为是弹栈操作,所有后弹出的数字在运算符前面
	private static int getResult(int a, String sym, int b){
		switch(sym){
		case "+" : return b + a;
		case "-" : return b - a;
		case "*" : return b * a;
		default : return b / a;
		}
	}
	//运算符等级,等级越高需要越先完成计算
	private static int getLevel(String sym){
		return sym.equals("+") || sym.equals("-") ? 1 : 2 ;
	}
	//最接近运算式起始的符号位置,用来确定马上要参与运算的数字和该数字之后的运算符
	private static int getLastIndex(String equation){
		int addIndex = equation.indexOf("+");
		int symIndex = -1;
		if(addIndex > -1){
			symIndex = addIndex;
		}
		int subIndex = equation.indexOf("-");
		if(subIndex > -1 && (symIndex == -1 || symIndex > subIndex)){
			symIndex = subIndex;
		}
		int mulIndex = equation.indexOf("*");
		if(mulIndex > -1 && (symIndex == -1 || symIndex > mulIndex)){
			symIndex = mulIndex;
		}
		int divIndex = equation.indexOf("/");
		if(divIndex > -1 && (symIndex == -1 || symIndex > divIndex)){
			symIndex = divIndex;
		}
		return symIndex;
	}
}

 

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值