算法训练 表达式计算
时间限制:1.0s 内存限制:256.0MB
提交此题
问题描述
输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
输入一行,包含一个表达式。
输出格式
输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
将表达式的式子优先级写好就行了
运用栈
例如1+(2+3)*(2+1)
最开始我们定义char类型栈str2,int类型栈str1
第一步,扫描字符串str,第一个为1,加入栈str1
第二步,发现+符号,加入str2
第三部,发现(符号,比+优先级高,加入str2
第三步,发现2,加入str1
第四步,发现+,比(优先级高,加入队列str2
第五步,发现3,加入str1
第六步,发现),比+优先级低,计算+前后两个值,并删除栈顶元素+
第七步,现在栈顶元素为(,继续扫描,又扫描到了),优先级相同,删除栈顶元素(,
。。。。。。。。。。。。。。。
如此扫描下去,最后str1中的栈顶元素就是求的值了
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <iostream>
#include <cstring>
using namespace std;
int priority(char x,char y)///优先级,-1前者小于后者,加入栈,0优先级相同,删除栈顶,1优先级大于后者,直接计算值
{
switch(x)
{
case '+':
if(y=='+'||y=='-'||y==')'||y=='#')
return 1;
else return -1;
case '-':
if(y=='+'||y=='-'||y==')'||y=='#')
return 1;
else return -1;
case '*':
if(y=='(')
return -1;
else return 1;
case '/':
if(y=='(')
return -1;
else return 1;
case '(':
if(y==')')
return 0;
else return -1;
case ')':
return 1;
case '#':
if(y=='#')
return 0;
else return -1;
}
}
int compute(int x,char p,int y)
{
if(p=='+')
return x+y;
if(p=='-')
return x-y;
if(p=='*')
return x*y;
if(p=='/')
return x/y;
}
int main()
{
char str[101];
stack<int> str1;
stack<char> str2;
char sttr[2]="#";
scanf("%s",str);
strcat(str,sttr);
str2.push('#');
int i=0;
while(str[i]!='\0')
{
int num=0;
while(str[i]>='0'&&str[i]<='9')
{
num=num*10+str[i]-'0';
i++;
}
if(num!=0)
str1.push(num);
if(priority(str2.top(),str[i])==-1)
{
str2.push(str[i]);
}
else if(priority(str2.top(),str[i])==0)
str2.pop();
else
{
while(priority(str2.top(),str[i])==1)
{
char p=str2.top();
str2.pop();
int y=str1.top();
str1.pop();
int x=str1.top();
str1.pop();
str1.push(compute(x,p,y));
}
if(priority(str2.top(),str[i])==0)
{
str2.pop();
}
else
str2.push(str[i]);
}
i++;
}
cout<<str1.top()<<endl;
return 0;
}