蓝桥杯 表达式计算

原题链接

蓝桥杯 算法训练 表达式计算

解题思路

源代码

参考算法笔记(胡凡)

#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
struct node{
	int num; //操作数
	char op; //操作符
	bool flag; // true为操作数,false为操作符 
};
queue<node> q; // 后缀表达式 
stack<node> s; // 操作符栈 
map<char, int> mp; // 表示操作符的优先级 
void change(string str){// 中缀表达式转后缀表达式
	node temp;
	for(int i=0; i<str.length();){
		// 遇到操作符压入栈 
		if(str[i] >= '0' && str[i] <= '9'){
			temp.flag = true;
			temp.num = str[i++]-'0';
			while(i<str.length() && str[i]>='0' && str[i]<='9'){ // 注意操作数可能不止一位 
				temp.num = temp.num*10 + (str[i] - '0');
				i++;
			}
			q.push(temp);
		}
		else{
			temp.flag = false;
			temp.op = str[i];
			if(str[i] == '(') s.push(temp); // 遇到左括号压入栈 
			else if(str[i] == ')'){
				// 遇到右括号就把符号栈中的弹到后缀表达式中直到遇到左括号 
				node tp;
				while(!s.empty()){
					tp = s.top();
					if(tp.flag==false && tp.op=='('){
						s.pop(); // 注意(要弹出去,不进后缀表达式 
						break;
					}
					q.push(tp);
					s.pop();
				}
				// 右括号和左括号都不需要出现在后缀表达式中 
			}
			else{
				// 只要当前操作符不比栈顶操作符高,就不断将操作符栈中的元素弹到后缀表达式中 
				while(!s.empty() && mp[str[i]]<=mp[s.top().op]){
					q.push(s.top());
					s.pop();
				}
				s.push(temp);
			}
			i++;
		}
	} 
	while(!s.empty()){
		q.push(s.top());
		s.pop();
	}
} 
int calc(){ // 计算后缀表达式的值 
	int temp1, temp2;
	node cur, temp;
	while(!q.empty()){
		cur = q.front();
		q.pop();
		if(cur.flag) s.push(cur); //操作数直接压入栈
		else{
			// 如果是操作符
			temp2 = s.top().num;
			s.pop();
			temp1 = s.top().num;
			s.pop();
			temp.flag = true;
			if(cur.op == '+') temp.num = temp1 + temp2;
			else if(cur.op == '-') temp.num = temp1 - temp2;
			else if(cur.op == '*') temp.num = temp1 *temp2;
			else temp.num = temp1 / temp2;
			s.push(temp);
		} 
	}
	return s.top().num;
}
int main(){
	mp['+'] = mp['-'] = 1;
	mp['*'] = mp['/'] = 2;
	string str;
	cin>>str;
	while(!s.empty()) s.pop();
	change(str);
	printf("%d", calc());
	return 0;
}
发布了110 篇原创文章 · 获赞 15 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40486952/article/details/105000315