leetcode:Basic Calculator II

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +-*/ operators and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:

"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5

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

题目分析:

看到计算表达式,就想到计算机可以顺序计算的后缀表达式表达式。所以本题可以分两个步骤解决。

1. 将表达式变为后缀表达式。主要是运算符压栈出栈顺序

2. 计算后缀表达式 so easy

注意计算表达式的时候后,要考虑到数字是10进制数,可能是多位

注意空格的特殊处理

注意单操作数处理

具体代码如下:

public static int calculate(String s) {
		int res = 0;
		Stack<Character> cal = new Stack<Character>();
		int len = s.length();
		StringBuffer bf = new StringBuffer();
		List<Object> list = new ArrayList<Object>();
		for (int i = 0; i <= len - 1; i++) {
			char ch = s.charAt(i);
			switch (ch) {
			// 注意构建后缀表达式的时候,符号压栈一定要记得优先级高的或者同等优先级的都要先弹出
			case ' ':
				break;// 空格特殊处理
			case '+':
				int para1 = getInt(bf.toString());
				list.add(para1);
				bf = new StringBuffer();
				while ((!cal.empty())
						&& ((cal.peek() == '*') || cal.peek() == '/'
								|| cal.peek() == '-' || cal.peek() == '+')) {
					char c1 = cal.pop();
					list.add(c1);
				}
				cal.push(ch);
				break;
			case '-':
				int para2 = getInt(bf.toString());
				list.add(para2);
				bf = new StringBuffer();
				while ((!cal.empty())
						&& ((cal.peek() == '*') || cal.peek() == '/'
								|| cal.peek() == '-' || cal.peek() == '+')) {
					char c1 = cal.pop();
					list.add(c1);
				}
				cal.push(ch);
				break;
			case '*':
				int para3 = getInt(bf.toString());
				list.add(para3);
				bf = new StringBuffer();
				while ((!cal.empty())
						&& ((cal.peek() == '*') || cal.peek() == '/')) {
					char c1 = cal.pop();
					list.add(c1);
				}
				cal.push(ch);
				break;
			case '/':
				int para4 = getInt(bf.toString());
				list.add(para4);
				bf = new StringBuffer();
				while ((!cal.empty())
						&& ((cal.peek() == '*') || cal.peek() == '/')) {
					char c1 = cal.pop();
					list.add(c1);
				}
				cal.push(ch);
				break;
			default:
				bf.append(ch);
				break;

			}
		}
		// 循环处理完了,最后一个数字还未处理一定要处理
		int para = getInt(bf.toString());
		list.add(para);

		// 记得把未处理完的运算符依次压栈
		while (!cal.empty()) {
			list.add(cal.pop());
		}
		res = calcu(list);
		return res;
	}

	//给一个字符串,获取对应的数字值
	public static int getInt(String s) {
		int res = 0;
		int len = s.length();
		for (int i = 0; i < len; i++) {
			char ch = s.charAt(i);
			int index = (int) (ch - '0');
			res += index*Math.pow(10, len - 1 - i);
		}
		return res;
	}
	
	
	/*计算后缀表达式的时候遇到数字压栈,遇到符号弹出两个数计算,计算完了的结果压栈*/
	public static int calcu(List<Object> list)
	{
		if(list.size()<1) return 0;
		Stack<Integer> cal = new Stack<Integer>();
		for(int i=0;i<list.size();i++)
		{
			Object obj=list.get(i);
			if(obj instanceof Integer)
			{
				cal.push((Integer) obj);
			}
			else if(obj instanceof Character)
			{
				char ch=(Character)obj;
				
				/*栈是先进后出,注意操作数顺序*/
				int b=cal.pop();
				int a=cal.pop();
				int fin=0;
				if(ch=='+')
				{
					fin=a+b;
				}
				else if(ch=='-')
				{
					fin=a-b;
				}
				else if(ch=='*')
				{
					fin=a*b;
				}
				else if(ch=='/')
				{
					fin=a/b;
				}
				cal.push(fin);
			}
		}
		if(!cal.empty())
		   return cal.pop();
		else
			//注意只有一个操作数的情况
			return (Integer)list.get(0);
	}
	
	@Test
	public void case1()
	{
		String s="3+2*2";
		int actual=calculate(s);
		int res=7;
		Assert.assertEquals(res, actual);
	}
	
	@Test
	public void case2()
	{
		String s="3/2";
		int actual=calculate(s);
		int res=1;
		Assert.assertEquals(res, actual);
	}
	
	@Test
	public void case3()
	{
		String s="3+5/2";
		int actual=calculate(s);
		int res=5;
		Assert.assertEquals(res, actual);
	}
	
	@Test
	public void case4()
	{
		String s="3-11/2";
		int actual=calculate(s);
		int res=-2;
		Assert.assertEquals(res, actual);
	}
	
	@Test
	public void case5()
	{
		String s="100000/1/2/3/4/5/6/7/8/9/10";
		int actual=calculate(s);
		int res=0;
		Assert.assertEquals(res, actual);
	}
	
	@Test
	public void case6()
	{
		String s=" 30";
		int actual=calculate(s);
		int res=30;
		Assert.assertEquals(res, actual);
	}
	
	@Test
	public void case7()
	{
		String s="1-1+1";
		int actual=calculate(s);
		int res=1;
		Assert.assertEquals(res, actual);
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值