题目:http://www.sqyoj.club/problem.php?id=1038
解题思路:模拟算法
引入数字栈,操作符栈
预处理:表达式加上一对括号,目的是将右括号作为停止标记
1.当前字符为左括号,则一直进操作符
2.当前字符是负号,且前一个字符是左括号,则将负号存入到操作符栈,在数字栈里存入数字0
3.当前字符是数字,则进数字栈
4.当前字符不是数字,也不是右括号,则与操作符栈栈顶元素比较,
4.1如果优先级低:
则数字栈出栈两个数字,操作符栈出栈一个操作符,进行运行,把运算结果入到数字栈,
反复进行,直到当前字符优先级高为止,然后把当前字符入操作符栈
4.2如果优先级高:
则当前字符入操作符栈,继续扫描读入
5.当前字符是右括号,则与往前算,直到操作符栈顶元素是左括号,然后将左括号出栈
AC代码:
/*
解题思路:模拟算法
引入数字栈,操作符栈
预处理:表达式加上一对括号,目的是将右括号作为停止标记
1.当前字符为左括号,则一直进操作符
2.当前字符是负号,且前一个字符是左括号,
则将负号存入到操作符栈,在数字栈里存入数字0
3.当前字符是数字,则进数字栈
4.当前字符不是数字,也不是右括号,则与操作符栈栈顶元素比较,
4.1如果优先级低:
则数字栈出栈两个数字,操作符栈出栈一个操作符,进行运行,把运算结果入到数字栈,
反复进行,直到当前字符优先级高为止,然后把当前字符入操作符栈
4.2如果优先级高:
则当前字符入操作符栈,继续扫描读入
5.当前字符是右括号,则与往前算,直到操作符栈顶元素是左括号,然后将左括号出栈
*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char str[300];
char stack1[300];//操作符栈
int stack2[300];//数字栈
int top1,top2;
int pri(char c){//返回优先级数
switch(c) {
case '+':return 1;break;
case '-':return 1;break;
case '*':return 2;break;
case '/':return 2;break;
case '(':return 0;break;
default:return 3;break;
}
}
int cal(int x,char c,int y){
switch (c) {
case '+':return x+y;break;
case '-':return x-y;break;
case '*':return x*y;break;
case '/':return x/y;break;
default:
int z=1;
for(int i=1;i<=y;i++) z=z*x;
return z;
break;
}
}
int main(){
//读入,并初始化
scanf("%s",str+1);
int len=strlen(str+1);
str[len+1]=')';
str[0]='(';
len+=2;
//扫描读入
int i=0;
while(i<len){
if(str[i]=='(')//扫描到(,则一直读到不是(为止
while(str[i]=='('){
stack1[++top1]='(';
i++;
}
if(str[i]>='0'&&str[i]<='9'){//读取数字
int x=0;
while(str[i]>='0'&&str[i]<='9'){
x=x*10+str[i]-'0';
i++;
}
stack2[++top2]=x;//数字进栈
}
/*******处理操作符*******/
//处理表达式中左括号后跟负号的情况
if(str[i]=='-'&&str[i-1]=='('){
//不能写成if(str[i]=='-'&&stack1[top1]=='('){
stack2[++top2]=0;
stack1[++top1]=str[i];
i++;
continue;
}
//当前字符是)时
if(str[i]==')'){
while(stack1[top1]!='('){
int x=stack2[top2-1],y=stack2[top2];
top2-=2;
char c=stack1[top1];
top1--;
int z=cal(x,c,y);
stack2[++top2]=z;
}
//到这里,操作符栈顶元素是(
top1--;
i++;
}
//当前字符不是)时
else{
//比较当前操作符(还未入栈)与操作符栈顶元素优先级
if(pri(str[i])<=pri(stack1[top1])){//当前操作符级别低
while(pri(str[i])<=pri(stack1[top1])){
//定义(优先级为0,这里用到了
//反复往前,例:3*4^2-5
int x=stack2[top2-1],y=stack2[top2];
top2-=2;
char c=stack1[top1];
top1--;
int z=cal(x,c,y);
stack2[++top2]=z;
}
//当前操作符要进栈
stack1[++top1]=str[i];
i++;
}
else{
//当前操作符进栈
stack1[++top1]=str[i];
i++;
}
}
}
cout<<stack2[top2];
return 0;
}