面试题 16.26. 计算器

该博客介绍了如何计算包含正整数、加减乘除的算术表达式的结果,提供了解题思路和对应的Java代码实现。第一种方法通过正则匹配数字并逐个处理操作符,第二种方法则是先将表达式按操作符拆分成数字列表再进行计算。两种方法均不使用内置库函数eval,旨在展示基础算法实现。
摘要由CSDN通过智能技术生成

给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。

表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格  。 整数除法仅保留整数部分。

示例 1:

输入: "3+2*2"
输出: 7
示例 2:

输入: " 3/2 "
输出: 1
示例 3:

输入: " 3+5 / 2 "
输出: 5


说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。
 

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/calculator-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

解题思路1:对应代码行Line78-115

1、用正则表达式去除空格

2、因为个人原因一时间想不到很好的办法去处理多位数字,于是偷懒再次用正则抽取出所有数字。

3、根据操作符,+-操作数数字入栈,*/操作数取出栈顶数字算出结果入栈

4、出栈加和得出结果

 

解题思路2:对应代码行Line18-76

对上面的方法做了一个小小的优化。

1、用正则表达式去除空格

2、依次取数字,并根据数字长度取操作符

3、根据操作符,+-操作数数字入栈,*/操作数取出栈顶数字算出结果入栈

4、出栈加和得出结果

综上,其实都算不上是很棒的解题,但是比较容易想到的思路。思路2取数字的时候,其实是多读了一位操作符,如果能够合理利用应该 也能提升点滴性能。

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class SolutionCalu {

	public static void main(String[] args) {
		SolutionCalu cal = new SolutionCalu();
		String s = " 13 +2*3+6-4*2 +1 ";
		int res = cal.calculate(s);
		System.out.println("res:"+res);
		
		s = " 13+5 / 2";
		res = cal.calculate(s);
		System.out.println("res:"+res);
	}
	
	public int calculate(String s) {
    	Stack<Integer> values = new Stack<Integer>();
    	s=s.replaceAll(" ", "");
    	
    	int index = 0;
    	int firstRes[] = getNextNum(s,index);
    	values.push(firstRes[0]);
    	System.out.println("0:"+values.peek());
    	index += firstRes[1];
    	System.out.println("0:"+index);
    	while(index < s.length()) {
    		char tmp = s.charAt(index);
    		switch(tmp) {
    			case '+':
    				firstRes = getNextNum(s,++index);
    		    	values.push(firstRes[0]);
    		    	index += firstRes[1];
    				break;
    			case '-':
    				firstRes = getNextNum(s,++index);
    		    	values.push(-firstRes[0]);
    		    	index += firstRes[1];
    				break;
    			case '*':
    				firstRes = getNextNum(s,++index);
    				values.push(values.pop() * firstRes[0]);
    				index += firstRes[1];
    				break;
    			case '/':
    				firstRes = getNextNum(s,++index);
    				values.push(values.pop() / firstRes[0]);
    				index += firstRes[1];
    				break;
    			default :
    				break;		
    		}
    	}
    	
    	int result = 0;
		while(!values.isEmpty()) {
			result += values.pop();
		}
		return result;
    }
	
	private int[] getNextNum(String s, int startIndex) {
		int[] result = new int[2];
		int endIndex = s.length();
		for(int i= startIndex;i<s.length();i++) {
			if(!Character.isDigit(s.charAt(i))) {
				endIndex = i;
				break;
			}
		}
		
		result[0] = Integer.parseInt(s.substring(startIndex, endIndex));
		result[1] = endIndex - startIndex;
		return result;
	}
	
    public int calculate2(String s) {
    	Stack<Integer> values = new Stack<Integer>();
    	s=s.replaceAll(" ", "");
    	
    	List<Integer> list = new ArrayList<>();
    	for(String tmp : s.split("\\+|-|\\*|/")) {
    		list.add(Integer.parseInt(tmp));
    	}
    	
    	int index = 0;
    	values.push(list.get(index++));
    	for(int i=0;i<s.length();i++) {
    		char tmp = s.charAt(i);
    		switch(tmp) {
    			case '+':
        			values.push(list.get(index++));
    				break;
    			case '-':
        			values.push(-list.get(index++));
    				break;
    			case '*':
    				values.push(values.pop() * list.get(index++));
    				break;
    			case '/':
    				values.push(values.pop() / list.get(index++));
    				break;
    			default :
    				break;		
    		}
    		
    	}
    	
    	int result = 0;
		while(!values.isEmpty()) {
			result += values.pop();
		}
		return result;
    }
    

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值