题目描述
计算非负整常数四则运算表达式,可用的运算符有:+ - * / ( ) 。
输入格式
一组非负整常数四则运算表达式,每个表达式输入一行,长度不超过1024个字符,每对括号内一定包含数字。
输出格式
每个表达式的计算结果输出一行,错误的表达式输出error。
输入样例
12+5
-4-7
3-*5
((12-3)/2)+5
3+7/(2-2)
输出样例
17
error
error
9
error
数据范围与提示
算法流程:
E1:设立运算符栈和操作数栈;
E2:开始运算符#入栈,向表达式串尾添加结束运算符#;
E3:逐词读入表达式,并处理:
E31:若读入为操作数,则入栈;
E32:若读入为运算符,则与栈顶运算符相比较:
E321:若栈顶运算符优先级高于读入运算符:
弹出栈顶运算符和两个操作数,计算并将结果入栈,执行步骤E32;
E322:若栈顶运算符优先级低于读入运算符:
则将读入运算符入栈,执行步骤E3;
E323:若栈顶运算符优先级等于读入运算符:
若为#,计算结束,若为括号,则弹出运算符,执行步骤E3。
E4:检查栈状态,得到计算结果;
代码展示
核心思想:将中缀表达式转换成后缀表达式再进行运算。
注意:①若括号不能匹配,则表达式错误,所以先进行括号匹配判断。
②本代码存在的漏洞:用-1作为错误返回值,若计算结果也为-1,则无法分辨。因为楼主没改就通过了所以不改了,想要更完善,可以再加一点判断条件来区别。
#include<bits/stdc++.h>
#include<iostream>
#include<stack>
#include<string>
#include<cctype>
using namespace std;
//一点废话写在前面
//取名废,干脆给函数取名“没名字”了
//栈test一开始只是想test,没想到成了,名字就这样了
//为了各部分功能更明了,还是建议大家改成自己习惯的名字...
int noName(string org){
int temp=0;
stack<char>test;
int num[100]={0};
int index=0;
char op[100];
stack<int>number;
int flag=0;
for(int i=0;i<org.length();++i){
char tp=org[i];//方便调试时查看当前处理字符
if(isdigit(org[i])){
temp*=10;
temp+=org[i]-'0';
flag=1;
}
else{
if(flag){//正在拼写数字
num[index]=temp;//数存入数字栈 atoi(temp.c_str())
op[index]='!';
index++;
flag=0;
temp=0;
}
if(org[i]=='#'){//读到末尾了
while(!test.empty()){
op[index++]=test.top();
test.pop();
}
break;
}
else{//读到符号
if(test.empty()||org[i]=='('){
test.push(org[i]);
}
else if(org[i]==')'){//如果是右括号,出栈到左括号
while(!test.empty() && test.top()!='('){
op[index++]=test.top();
test.pop();
}
if(!test.empty()) test.pop();//弹出左括号
else return -1;
}
else if(org[i]=='*'||org[i]=='/'){//如果是乘除,则乘除出栈,新符号入栈
while(!test.empty() && (test.top()=='*'||test.top()=='/'))
{
op[index++]=test.top();
test.pop();
}
test.push(org[i]);
}
else{//如果是加减
while(!test.empty() && test.top()!='('){
op[index++]=test.top();
test.pop();
}
test.push(org[i]);
}
}
}
}
//后缀表达式求值
int temp1=0;
int temp2=0;
for(int i=0;i<index;i++){
if(op[i]=='!')//数字入栈
{
number.push(num[i]);
}
else{
temp1=number.top();
number.pop();
if(number.empty()) return -1;
temp2=number.top();
number.pop();
switch(op[i]){
case '+':
number.push(temp2+temp1);
break;
case '-':
number.push(temp2-temp1);
break;
case '*':
number.push(temp2*temp1);
break;
case '/':
if(temp1==0) return -1;//除0时error
number.push(temp2/temp1);
break;
}
}
}
return number.top();
}
int brackets(string org){//检查括号匹配情况
int mark=0;
for(int i=0;i<org.length();i++){
if(org[i]=='(') mark++;
if(org[i]==')') mark--;
}
return mark;
}
int main(){
string org;
while(cin>>org){
if(brackets(org)){
cout<<"error"<<endl;
}
else{
org+='#';
int result;
result=noName(org);
if(result==-1){
cout<<"error"<<endl;
}
else cout<<result<<endl;
}
}
return 0;
}