C++ 逆波兰表达式求值

注意:下面的实现默认传入的表达式是合法的,在计算过程中没有对表达式的正确性检验

方法:遍历表达式,根据不同的情况进行不同处理:

  1. 如果遇到数字,就压入栈中
  2. 如果遇到运算符,判断是单目还是双目运算符:
    (a) 单目:从栈取出1个操作数进行运算,并将结果再次存入栈中
    (b) 双目:从栈取出2个操作数进行运算,并将结果再次存入栈中
  3. 遍历结束后,栈中剩下一个数,就是结果

主要逻辑

实现主要逻辑的函数:

double evaluate(const string& expression) {
	stack<double> s; // 存数的栈
	int i = 0; // 遍历用的下标
	int len = expression.length();
	double result = 0; // 表达式结果
	while (i < len) { // 遍历
		if (isdigit(expression[i])) { // 如果是数字,就存入栈
			double operand = get_operand(expression, i);
			s.push(operand);
		}
		else if (expression[i] == '!') { // 如果是单目运算符,就取1个数计算
			double operand = s.top();
			s.pop();
			s.push(operate('!', operand)); // 结果存回栈中
		}
		else { // 如果是双目运算符,就取2个数计算
		// !注意取数和运算时传入的顺序!
			double operand2 = s.top();
			s.pop();
			double operand1 = s.top();
			s.pop();
			s.push(operate(expression[i], operand1, operand2)); // 结果存回栈中
		}
		i++;
	}
	return s.top();
}

在上面的主要逻辑中封装了一些辅助函数,使得主要逻辑比较清晰,下面给出这些辅助函数:

辅助函数们

从字符串中获取数字

字符串中的数字可能为多位且为浮点数,因此可能需要连续的取字符以获得一个完整的数,要注意的是传入的下标i引用
使用了std::stod()进行stringdouble的转换。

double get_operand(const string& expression, size_t& i) {
	string operand = "";
	int len = expression.length();
	while (isdigit(expression[i]) && i < len) {
		operand.push_back(expression[i++]);
	}
	return stod(operand);
}

计算阶乘

int factorial(int n) {
	int result = 1;
	for (int i = 2; i <= n; ++i) result *= i;
	return result;
}

单目运算符计算

这里现在还只有!阶乘这一个运算符,你也可以自行添加。

int operate(char unary_operator, double operand) {
	int result;
	switch (unary_operator) {
	case '!':
		result = factorial((int)operand);
		break;
	}
	return result;
}

双目运算符计算

%^运算中使用了std::fmod()std::pow()

double operate(char binary_operator, double operand1, double operand2) {
	double result;
	switch (binary_operator) {
	case '+':
		result = operand1 + operand2;
		break;
	case '-':
		result = operand1 - operand2;
		break;
	case '*':
		result = operand1 * operand2;
		break;
	case '/':
		result = operand1 / operand2;
		break;
	case '%':
		result = fmod(operand1, operand2);
		break;
	case '^':
		result = pow(operand1, operand2);
		break;
	}
	return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值