163.Basic Calculator

本文介绍了一个简易计算器的设计与实现过程,该计算器能解析并计算包含加减运算及括号的简单数学表达式。文章详细阐述了如何通过字符串处理、栈结构应用来逐步去除表达式中的括号,并最终计算出表达式的值。

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -non-negative integers and empty spaces .

You may assume that the given expression is always valid.

Some examples:

"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23

Note: Do not use the eval built-in library function.

 计算表达式的值。 
 Step1:把字符串s按照()+-进行分割成字符串数组; 
 Step2:新建一个stack存放目前计算的值;
 Step3:依次遍历字符串数组中的每个字符串;如果遇到的是左括号(或+或-或数字则压栈,
 如果是右括号)则把弹栈直到遇到(,把括号内的值计算后再压栈; 
 Step4:把栈内的元素进行运算。

 第三步相当于去括号,第四步计算去掉括号之后的值。

/**
	 * 计算表达式的值。 
	 * Step1:把字符串s按照()+-进行分割成字符串数组; 
	 * Step2:新建一个stack存放目前计算的值;
	 * Step3:依次遍历字符串数组中的每个字符串;如果遇到的是左括号(或+或-或数字则压栈,
	 * 如果是右括号)则把弹栈直到遇到(,把括号内的值计算后再压栈; 
	 * Step4:把栈内的元素进行运算。
	 * 
	 * 第三步相当于去括号,第四步计算去掉括号之后的值。
	 */

	public int calculate(String s) {

		Stack stack = new Stack<String>();
		ArrayList<String> list = new ArrayList<String>();
		
		int sLen = s.length();
		int index = 0;
		StringBuilder sb;
		/*查分字符串为数字和括号+-,比如1 + 1拆分为1,+,1*/
		while(index<sLen){
			char c = s.charAt(index);
			/*如果遇到的是空格,则忽略*/
			if(c == ' '){
				index++;
				continue;
			}
			/*如果遇到的是符号,则入list*/
			if(c == '+' || c == '(' || c == ')' || c == '-' ){
				list.add(s.substring(index,index+1));
				index++;
			}else{//如果是数字则把当前的这数字取完
				sb = new StringBuilder();
				while(index<sLen && s.charAt(index)!='+' && s.charAt(index)!='-' 
						&& s.charAt(index)!='(' && s.charAt(index)!=')'
						&& s.charAt(index)!=' '){
					sb.append(s.charAt(index));
					index++;
				}
				list.add(sb.toString());
			}
		}
		
		int len = list.size();
		/* 如果list只有一个元素说明字符串s只有一个数字,直接返回即可 */
		if (len == 1) {
			return Integer.valueOf(list.get(0));
		}

		/*第一遍相当于把表达式中间的括号都去掉*/
		int i = 0;
		stack.add(list.get(0));// 先把第一个元素入栈
		i++;
		while (i < len) {
			String temp = list.get(i);
			if (temp.equals(")")) { // 如果是右括号)则把弹栈直到遇到(,把括号内的值计算后再压栈;
				EntreParentesis(stack);
			} else {
				stack.add(temp);
			}
			i++;
		}
		/*然后计算栈内表达式的值*/
		EntreParentesis(stack);

		return Integer.valueOf((String) stack.pop());
	}

/*
	 * 计算栈顶的一个括号内的值,现在栈顶的若干个元素如(5-2+3+4,
	 * 这个方法完成的工作就是通过把若干个栈顶元素(左括号之前包括左括号)弹栈计算得出10,然后把10压入栈
	 */
	private void EntreParentesis(Stack<String> stack) {
		int right;// 右操作数
		int left;// 左操作数
	
		/*把(5-2+3+4依次弹栈,然后再压入tempStack中*/
		Stack<String> tempStack = new Stack<String>();
		while (!stack.isEmpty() && !stack.peek().equals("(")) {
			tempStack.add(stack.pop());
		}
		
		if (!stack.isEmpty()) {//如果栈不为空,则需要弹出"(",然后把结果压栈;如果栈为空,比如计算前栈内只有5这一个数字
			stack.pop();
		}
		
		/*计算tempStack中表达式的值*/
		String val = (String) tempStack.pop();
		right = Integer.valueOf(val);
		while (!tempStack.isEmpty() ) {
			String oper = tempStack.pop();
			left = Integer.valueOf(tempStack.pop());
			if (oper.equals("+")) {
				right = left + right;
			} else {
				right = right - left;
			}
		}
		stack.add(right + "");
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值