2021-10-13每日刷题打卡

一、信息学OJ-1358:中缀表达式值(expr)

(1)题目描述

输入一个中缀表达式(由0-9组成的运算数、加+减-乘*除/四种运算符、左右小括号组成。注意“-”也可作为负数的标志,表达式以“@”作为结束符),判断表达式是否合法,如果不合法,请输出“NO”;否则请把表达式转换成后缀形式,再求出后缀表达式的值并输出。

注意:必须用栈操作,不能直接输出表达式的值。

【输入】

一行为一个以@结束的字符串。

【输出】

如果表达式不合法,请输出“NO”,要求大写。

如果表达式合法,请输出计算结果。

【输入样例】

1+2*8-9@

【输出样例】

8

(2)问题分析

        这道题的大致思想很好想,感觉这道题细节太多了,弱弱的我没有实现出来,最终借鉴了题解。。。

(3)代码实现

        

#include 
using namespace std;
stack  digit; 
stack  symbol;
string str; 
int len;
int level(char ch){
	if(ch=='+'||ch=='-') return 1;
	if(ch=='*'||ch=='/') return 2;
	return 0;
}
void calculation(){
	int a=digit.top();
	digit.pop();
	int b=digit.top();
	digit.pop();
	char ch=symbol.top();
	symbol.pop();
	if (ch == '+') digit.push(a + b); 
	if (ch == '-') digit.push(b - a);
	if (ch == '*') digit.push(a * b);
	if (ch == '/') digit.push(b / a);
}
void solve(){
	int x=0;
	bool tag=false;
	for(int i=0;i='0'&&str[i]<='9'){
			x=x*10+str[i]-'0';
			tag=true;
		}else{
			if(tag){
				digit.push(x);
				tag=false;
				x=0;
			}
			if(str[i]=='('){
				symbol.push(str[i]);
				continue;
			}
			if(str[i]==')'){
				while(symbol.top()!='('){
					calculation();
				}
				symbol.pop();
				continue;
			}
			while(!symbol.empty()&&level(symbol.top())>=level(str[i])){
				calculation();
			}
			symbol.push(str[i]);
		}
	}
	if (tag) { 
		digit.push(x);
	}
	while (!symbol.empty()) {
		calculation();
	}
	cout << digit.top() << endl;
}
bool check() { 
	if (len == 1) return level(str[0]) > 0 ? false : true;//数字或者字符 
	for (int i = 1; i < len; i ++) { 
		if (level(str[i]) && level(str[i-1])) return false;
	}
	int sum = 0;
	for (int i = 0; i < len; i ++) { 
		if (str[i] == '(') sum ++;
		else if (str[i] == ')') sum --;
	}
	return sum == 0;
}
 
int main()
{
	cin >> str;
	len = str.length() - 1;
	if (str[0] == '-') digit.push(0);
	if (!check()) { 
		cout << "NO" << endl;
	}
	else { 
		solve();
	}
	return 0;
}

        

你可能感兴趣的:(算法,算法)