题目:在一个表达式中,只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,请求出表达式的值。(“/”用整数除法)。
将中缀表达式转化成后缀表达式,一边转化,一边计算。
基本思路:
读取完字符串之后,扫描一遍,扫描一遍后,运算也同时结束,过程中将中缀表达式转化成后缀表达式,一边转化,一边计算。
1.如果碰到了数字,开始往数字栈放数字(考虑多位数情况)
2.如果碰到了 “(” 直接入符号栈
3.如果碰到了运算符,如果其优先级大于符号栈顶元素优先级,入栈;
否则,先计算符号栈顶元素和数字栈顶两元素的运算结果,并将结果入栈
(特别的,如果数字栈内元素不足2,那么不论哪一种运算符都要直接入栈)
4.如果碰到了 “)” 开始从两个栈往外提取元素,进行计算,直到符号栈顶元素是 “(” ,计算结束后要把 “(” 也取出,表示这一对括号内的表达式已经计算成一个结果了
5.特别的,“^”的优先级要大于 “*” 和 “/” (比较723和7 ^23的区别)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int IfNum(char ch)
{
if(ch<='9'&&ch>='0')
{
return 1;
}
return 0;
}
int Calculate(int a,char ch,int b)
{
if(ch=='*')
{
return a*b;
}
else if(ch=='/')
{
return a/b;
}
else if(ch=='-')
{
return a-b;
}
else if(ch=='+')
{
return a+b;
}
else
{
return pow(a,b);
}
}
int Comparechar(char a,char b)
{
int x = 0; //a的优先级
int y = 0; //b的优先级
if(a == '+' || a == '-')
{
x=1;
}
else if(a=='*'|| a=='/')
{
x=2;
}
else if(a=='^')
{
x=3;
}
else if(a=='(')
{
x=4;
}
if(b=='+'||b=='-')
{
y=1;
}
else if(b=='*'||b=='/')
{
y=2;
}
else if(b=='^')
{
y=3;
}
else if(b=='(')
{
y=4;
}
if(x > y)
{
return 1;
}
return 0;
}
int main()
{
char s[310];//主串
int num[310];//数字栈
char ch[310];//运算符栈
gets(s);
int topn, topc;
topn = 0;//数字栈的栈顶
topc = 0;//符号栈的栈顶
for (int i = 0; i < 310; i++)
{
num[i] = 0;
ch[i] = '0';
}
int i = 0;
while (i < strlen(s))
{
if (IfNum(s[i]))
{
while (IfNum(s[i]))
{
num[topn] = num[topn] * 10 + s[i++] - '0';
}
topn++;
continue;
}
else
{
if (s[i] == '(')
{
ch[topc++] = s[i];
}
else if (s[i] == ')')
{
while (ch[topc - 1] != '(')
{
num[topn - 2] = Calculate(num[topn - 2], ch[topc - 1], num[topn - 1]);
num[topn - 1] = 0;//数字栈顶元素用完之后要清零,否则影响之后的运算
topc--;
topn--;
}
topc--;//计算完括号内的式子后将左括号移除
}
else
{
if (topc == 0)//如果符号栈为空,则直接入栈
{
ch[topc++] = s[i];
}
else if (Comparechar(s[i], ch[topc - 1]))
{
//如果是当前运算符优先级比栈顶运算符优先级大 直接入栈
ch[topc++] = s[i];
}
else
{
//当前运算符优先级比栈顶运算符优先级小
while (!Comparechar(s[i], ch[topc - 1]))
{
if (ch[topc - 1] == '(')
{
break;
}
num[topn - 2] = Calculate(num[topn - 2], ch[topc - 1], num[topn - 1]);
num[topn - 1] = 0;
topc--;
topn--;
if (topc == 0)
{
break;
}
}
ch[topc++] = s[i];//计算完成之后,运算符进栈
}
}
}
i++;
}
while (topn != 1 && topc > 0) //在遍历整个字符串之后如果两个栈还有数据
{
num[topn - 2] = Calculate(num[topn - 2], ch[topc - 1], num[topn - 1]);
topn--;
topc--;
}
printf("%d", num[0]);//一旦数字栈里只剩一个数字 或者运算符栈没有符号了 那就停止计算
}