C++:表达式求值(四则运算)实现

基础版

请写一个整数计算器,支持加减乘三种运算和括号。

示例1
输入:
“1+2”
返回值:
3

示例2
输入:
“(2*(3-4))*5”
返回值:
-10

示例3
输入:
“3+2* 3* 4-1”
返回值:
26

#include<string>
#include<stack>
#include<iostream>
using namespace std;

#define N_OPTR 6
typedef enum { ADD, SUB, MUL, L_P, R_P, EOE } Operator;
class Solution {
public:
	/**
	* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
	* 返回表达式的值
	* @param s string字符串 待计算的表达式
	* @return int整型
	*/
	int solve(string s) {
		// write code here
		const char pri[N_OPTR][N_OPTR] = {
			/*           当前运算符    */
			/*      +   -   *   (   )  \0 */
			/* + */ '>','>','<','<','>','>',
			/* - */ '>','>','<','<','>','>',
			/* * */ '>','>','>','<','>','>',
			/* ( */ '<','<','<','<','=',' ',
			/* ) */ ' ',' ',' ',' ',' ',' ',
			/*\0 */ '<','<','<','<',' ','=',
		};

		stack<int> opnd;//运算数栈
		stack<char> optr;//运算符栈
		optr.push('\0');
		int i = 0;
		while (!optr.empty()) {
			char c = s[i];
			if (c >= '0' && c <= '9') {
				int l = i;	//记录整数的左边界
				while (s[i] >= '0' && s[i] <= '9') {
					i++;
				}
				int num = stoi(s.substr(l, i - l));
				opnd.push(num);
			}
			else {
				int first = toChar(optr.top());
				int second = toChar(c);
				switch (pri[first][second]) {
				case '<': optr.push(c); i++; break;
				case '=': optr.pop(); i++; break;
				case '>': {
					char op = optr.top();
					optr.pop();
					int r_op = opnd.top(); opnd.pop();
					int l_op = opnd.top(); opnd.pop();
					opnd.push(calcu(l_op, op, r_op));
					break;
				}
				default:exit(-1);
				}//switch
			}//else
		}//while
		return opnd.top();

	}

	int toChar(char top) {
		switch (top) {
		case '+':top = ADD; break;
		case '-':top = SUB; break;
		case '(':top = L_P; break;
		case ')':top = R_P; break;
		case '*': top = MUL; break;
		case '\0':top = EOE; break;
		default:break;
		}
		return top;
	}

	int calcu(int l_op, char op, int r_op) {
		switch (op) {
		case '+':return l_op + r_op; break;
		case '-':return l_op - r_op; break;
		case '*':return  l_op*r_op; break;
		default: exit(-1);
		}
	}
};

int main() {
	string str;
	while (cin >> str) {
		Solution sol;
		int res = sol.solve(str);
		cout << res << endl;
	}
	return 0;
}

进阶版

输入一个表达式(用字符串表示),求这个表达式的值。

保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

输入描述

输入一个算术表达式

输出描述

得到计算结果

示例1
输入:
3+2*{1+2*[-4/(8-6)+7]}
输出:
25

#include<string>
#include<stack>
#include<iostream>
using namespace std;

#define N_OPTR 11
typedef enum { ADD, SUB, MUL, DIV, L_P, R_P, L_Q, R_Q, L_S, R_S, EOE } Operator;
class Solution {
public:
	/**
	* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
	* 返回表达式的值
	* @param s string字符串 待计算的表达式
	* @return int整型
	*/
	double solve(string s) {
		// write code here
		const char pri[N_OPTR][N_OPTR] = {
			/*           当前运算符    */
			/*      +   -   *   /   (   )   [    ]   {   }  \0 */
			/* + */ '>','>','<','<','<','>','<','>','<','>','>',
			/* - */ '>','>','<','<','<','>','<','>','<','>','>',
			/* * */ '>','>','>','>','<','>','<','>','<','>','>',
			/* \ */ '>','>','>','>','<','>','<','>','<','>','>',
			/* ( */ '<','<','<','<','<','=','<',' ','<',' ',' ',
			/* ) */ ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
			/* [ */ '<','<','<','<','<',' ','<','=','<',' ',' ',
			/* ] */ ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
			/* { */ '<','<','<','<','<',' ','<',' ','<','=',' ',
			/* } */ ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
			/*\0 */ '<','<','<','<','<',' ','<','<','<','<','=',
		};

		stack<double> opnd;//运算数栈
		stack<char> optr;//运算符栈
		optr.push('\0');
		int i = 0;
		while (!optr.empty()) {
			char c = s[i];
			if (c >= '0' && c <= '9') {
				int l = i;	//记录整数的左边界
				while (s[i] >= '0' && s[i] <= '9') {
					i++;
				}
				int num = stoi(s.substr(l, i - l));
				opnd.push((double)num);
			}
			else {
				//补充单目运算符‘+’和‘-’在数字前的情况:向运算数栈内补0
				if (
					(c == '+' || c == '-')
					&& (i - 1 >= 0 && (s[i - 1] == '{' || s[i - 1] == '[' || s[i - 1] == '('))
					|| (i == 0)
					)
				{
					opnd.push(0.0);
				}
				int first = toChar(optr.top());
				int second = toChar(c);
				switch (pri[first][second]) {
				case '<': optr.push(c); i++; break;
				case '=': optr.pop(); i++; break;
				case '>': {
					char op = optr.top();
					optr.pop();
					double r_op = opnd.top(); opnd.pop();
					double l_op = opnd.top(); opnd.pop();
					opnd.push(calcu(l_op, op, r_op));
					break;
				}
				default:exit(-1);
				}//switch
			}//else
		}//while
		return opnd.top();

	}

	int toChar(char top) {
		switch (top) {
		case '+':top = ADD; break;
		case '-':top = SUB; break;
		case '(':top = L_P; break;
		case ')':top = R_P; break;
		case '[':top = L_Q; break;
		case ']':top = R_Q; break;
		case '{':top = L_S; break;
		case '}':top = R_S; break;
		case '*':top = MUL; break;
		case '/':top = DIV; break;
		case '\0':top = EOE; break;
		default:break;
		}
		return top;
	}

	double calcu(double l_op, char op, double r_op) {
		switch (op) {
		case '+':return l_op + r_op; break;
		case '-':return l_op - r_op; break;
		case '*':return  l_op*r_op; break;
		case '/':return l_op / r_op; break;
		default: exit(-1);
		}
	}
};

int main() {
	string str;
	while (cin >> str) {
		Solution sol;
		double res = sol.solve(str);
		cout << res << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值