面试题16.26 计算器


一、题目分析

输入一个字符串,是正整数、加(+)、减(-)、乘(*)、除(/)的算术表达式,设计一个计算器,计算该算术表达式的结果,表达式不包含括号()。整数除法仅保留整数部分。

二、使用步骤

1.解题思路

以表达式"2+3*4*5-10/6"计算为例,遍历该表达式进行计算的过程有如下几种情况:

  • 当前遇到的字符是运算符:由于未知后续运算符的优先级,所以将该运算符压入用于保存运算符的栈中,在后续遍历过程中再次遇到运算符,与当前栈顶的运算符进行比较,如果当前运算符的优先级小于或等于栈顶运算符的优先级,说明上一个运算符与相关数字可以进行运算。
  • 当前遇到的字符是数字位:该位置可能是一个单独的数字也可能是两位数的十位,需要继续向后遍历几位,确定遇到下一个运算符之前的数字的大小,将计算好的数字压入用于保存数字的栈中。

2.代码实现

利用一个unordered_map结构记录四个运算符的优先级。

class Solution {
public:
	//记录运算符号优先级的表
	unordered_map<char, int> table{
	{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};

	int operate(int a, int b, char op){
		if(op == '/' && a != 0) return a / b;
		else if(op == '-') return a - b;
		else if(op == '*') return a * b;
        else if(op == '+') return a + b;
		else 
            return 0;
	}
    int calculate(string s) {
        //移除表达式中的空格
        s.erase(remove(s.begin(), s.end(), ' '), s.end());
    	int res = 0;   //保存表达式结果
    	int i = 0;
    	stack<int> numStk;   //保存数值的栈
    	stack<char> opStk;   //保存运算符的栈
		while(i < s.size()){
			int num = 0;
			if(isdigit(s[i])){ //当前位为数字位
				while(isdigit(s[i])){ 
				num = num * 10 +(s[i] - '0');
				++i;
				}
				numStk.push(num);
			}else{ //当前位为运算符
				while(!opStk.empty() && table[s[i]] <=  table[opStk.top()]){ //当前运算符的优先级低于运算符栈栈顶运算符的优先级,可以计算上一步运算
					int b = numStk.top(); numStk.pop();
					int a = numStk.top(); numStk.pop();
					numStk.push(operate(a, b, opStk.top()));
					opStk.pop();
				}
				opStk.push(s[i]); ++i;
			}
		}
		//从两个栈中还原最终结果
		while(!opStk.empty() && !numStk.empty()){
			int b = numStk.top(); numStk.pop();
			int a = numStk.top(); numStk.pop();
			numStk.push(operate(a, b, opStk.top()));opStk.pop();
		}
		res = numStk.top(); 
		return res;
    }
};

注意事项:

  1. 题目中假设给出的表达式都是有效的,因此代码中省略了部分判断
  2. 除法运算/的除数不能为零
  3. 测试用例输入的字符串是含有空格的,因此第一步需要将给出字符串中的空格全部删除,删除字符串中空格采用erase和remove两个函数,具体用法如下:
  • remove
ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& val);

将[fist, last)范围内所有等于val的元素删除,删除是通过将等于val元素替换为下一个不等于val的元素来完成的,函数返回缩短后新范围的末尾。

  • erase
    采用string类型的成员函数erase:
iterator erase(const_iterator first, const_iterator last);

删除[first, last)范围内的字符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值