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;
}
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算术表达式是一个基本的数学问题,也是程序设计中的一个经典问题。在C语言中,可以使用数据结构来实现算术表达式。一个算术表达式由操作数、运算符和界限符组成,例如表达式"#(7 15)*(23-28/4)#"。操作数通常是正实数,运算符可以是加、减、乘、除等四种运算符,界限符包括左右括号和表达式起始、结束符号"#"。为了方便处理,在表达式的起始和结束位置都添加了界限符。 在C语言中,可以使用运算符优先法来解算术表达式。具体的步骤如下: 1. 建立两个栈,一个用来存储操作数,另一个用来存储运算符。可以使用C语言中的栈数据结构来实现这两个栈。 2. 根据运算符的优先级原则,遵循先乘除后加减的运算法则,对表达式进行逐个字符的扫描。 3. 当遇到操作数时,将其压入操作数栈中。 4. 当遇到运算符时,判断其与运算符栈顶的运算符的优先级,如果当前运算符的优先级大于或等于栈顶运算符的优先级,则将当前运算符入栈;否则,将运算符栈顶的运算符弹出,并执行相应的运算操作,直到当前运算符可以入栈。 5. 当遇到左括号时,将其入运算符栈。 6. 当遇到右括号时,将运算符栈中的运算符依次弹出,并执行相应的运算操作,直到遇到左括号。 7. 继续扫描表达式的下一个字符,重复步骤3-6,直到扫描完整个表达式。 8. 最后,操作数栈中剩余的操作数依次弹出,并执行相应的运算操作,即可得到表达式的最终结果。 通过以上步骤,我们可以使用C语言的数据结构来实现算术表达式。具体的代码实现可以参考引用中给出的解题思路,建立两个栈来分别存储操作数和运算符,并根据运算符的优先级进行相应的操作。最终可以得到算术表达式。 参考文献: [问题描述内容] [问题解答内容] [解题思路内容] #### 引用[.reference_title] - *1* *3* [数据结构:c++算术表达式](https://blog.csdn.net/weixin_43334673/article/details/103593409)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [数据结构 C++实现 算术表达式](https://blog.csdn.net/qq_54388490/article/details/123742067)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值