问题描述
输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
输入一行,包含一个表达式。
输出格式
输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
表达式长度不超过100,表达式运算合法且运算过程都在int内进行。
解题思路:将中缀表达式转化为后缀表达式
转化方法见:http://blog.csdn.net/sgbfblog/article/details/8001651
此题中分别使用符号栈和数值栈进行运算
源代码:
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<stack>
#include<stdlib.h>
using namespace std;
stack<char> str;
//符号栈
stack<int> num;
//数值栈
void sym(char ch)
//此函数用于将中缀表达式通过栈的操作转化为后缀表达式,并在转化的过程中同时进行后缀表达式的运算
{
if(num.size()<2)
//数值栈的元素个数小于两个时,仅将符号压入栈中,不进行运算
{
str.push(ch);
}
else
{
if(ch=='+'||ch=='-'||ch==')')
//当前运算符为+或-或)时,从栈顶向下进行运算
{
while(str.size()&&str.top()!='(')
{
int num1=num.top();
num.pop();
int num2=num.top();
num.pop();
//取出数值栈的前两位数字
if(str.top()=='+')
{
num.push(num1+num2);
}
else if(str.top()=='-')
{
num.push(num2-num1);
}
else if(str.top()=='*')
{
num.push(num1*num2);
}
else if(str.top()=='/')
{
num.push(num2/num1);
}
//将得到的结果压入数值栈
str.pop();
//删除符号栈栈顶元素
}
if(ch==')')
{
str.pop();
}
//当前符号为)时,必将运算至(停止,所以无需将)压入栈中,并且要将(删除
else
{
str.push(ch);
}//将运算符压入符号栈中
}
else if(ch=='(')
{
str.push(ch);
}
//运算符为(时,直接压入符号栈
else if(ch=='*'||ch=='/')
{
while(str.top()=='*'||str.top()=='/')
//当前运算符为*或/时,只有*/运算符优先级大于等于此时运算符的优先级
{
int num1=num.top();
num.pop();
int num2=num.top();
num.pop();
if(str.top()=='*')
{
num.push(num1*num2);
}
else
{
num.push(num2/num1);
}
str.pop(); //删除栈顶元素
}
str.push(ch);
//将当前运算符压入符号栈中
}
}
}
void sym2()
//此函数用于将所有运算符和数值压入栈后,运算并未完成的情况下,完成后缀表达式的运算
{
while(str.size())
//从栈顶一直向下运算直到符号栈为空
{
int num1=num.top();
num.pop();
int num2=num.top();
num.pop();
if(str.top()=='+')
{
num.push(num1+num2);
}
else if(str.top()=='-')
{
num.push(num2-num1);
}
else if(str.top()=='*')
{
num.push(num1*num2);
}
else if(str.top()=='/')
{
num.push(num2/num1);
}
//将结果压入数值栈中
str.pop();
//删除符号栈栈顶元素
}
}
int main()
{
int n,i,k=0,Num;
//Num用来记录数值
string ch;
char number[10];
getline(cin,ch);
n=ch.length();
for(i=0;i<n;i++)
{
if('0'<=ch[i]&&ch[i]<='9')
{
number[k]=ch[i];
k++;
//将数字字符存入number字符串中
}
else
{
number[k]='\0';
//在数字字符串末尾插入结束符
if(number[0]!='\0')
//区分两个运算符连续出现的情况
{
Num=strtol(number,NULL,10);/
/数字字符串转化为数字
num.push(Num);//将数值压入数值栈
}
sym(ch[i]);
//
number[k]='0';//将此前的结束符更改为非结束符字符,以便之后数值的转化
k=0;
}
}
if('0'<=ch[n-1]&&ch[n-1]<='9')
//中缀表达式结尾为数字时,由上面的循环可知,最后一位数值不会被压入数值栈中
{
number[k]='\0';
Num=strt`
l(number,NULL,10);
num.push(Num);
}
//将结尾数字压入数值栈
sym2();//完成剩余的运算
cout<<num.top()<<endl;
return 0;
}