7-2 表达式求值 (10 分)
给定一个中缀表达式,请编写程序计算该表达式的值。表达式包含+、-、*、\、(、),所有运算均为二元运算,操作数均为正整数,但可能不止一位,不超过5位。运算结果为整数,值域为[−2 ^31,2 ^31)。除法运算结果若为小数则进行截尾取整。若除法运算中除数为0,则输出ILLEGAL。
- 输入格式:
输入为一个字符串,表示中缀表达式。 - 输出格式:
输出为一个整数,为表达式的值;或者为一个字符串ILLEGAL。 - 输入样例1:
5+(10*2)-6 - 输出样例1:
19 - 输入样例2:
8*(999+1) - 输出样例2:
8000 - 输入样例3:
1+5/(1-1) - 输出样例3:
ILLEGAL
思路:用数组模拟的栈。读取完字符串之后,先扫描一遍(扫描同时计算)。
将表达式按照字符串输入,自定义函数识别字符数字并转换。
首先,如果是数字,则进入数字栈;
如果不为数字,(1)判断是否为左括号,直接入符号栈;(2)判断是否为运算符,如果是则进一步判断此符号与符号栈栈顶优先级,如果优先级大于栈顶则入栈,否则(条件:当前符号优先级小于栈顶符号)计算数字栈栈顶元素与栈顶下一元素和符号栈栈顶,将值赋给数字栈栈顶元素,同时数字栈和符号栈各退一格(如果符号栈为空则不能继续计算,此时跳出循环,将符号入符号栈)。
如果是右括号,符号栈取栈顶元素,数字栈取栈顶两元素进行计算,直到符号栈遇到左括号,计算结束后再把左括号去除。
在每次计算完时首先将数字栈栈顶元素出栈(将当前数组元素赋值为0,下一个栈顶存这一步计算的结果)
#include<stdio.h>
#include<string.h>
int in(char ch)
{
if (ch <= '9' && ch >= '0')
return 1;
return 0;
}
int A(int a, char c, int b,int *flag)
{
if (c == '*')
return a * b;
else if (c == '/') {
if (b == 0)
*flag = 1;
else
return a / b;
}
else if (c == '-')
return a - b;
else if (c == '+')
return a + b;
}
int B(char a, char b)
{
int x = 0;
int y = 0;
if (a == '+' || a == '-')
x = 1;
else if (a == '*' || a == '/')
x = 2;
else if (a == '(')
x = 3;
if (b == '+' || b == '-')
y = 1;
else if (b == '*' || b == '/')
y = 2;
else if (b == '(')
y = 3;
if (x > y)return 1;
return 0;
}
int main()
{
char s[1000];
int num[1000];
char ch[1000];
int flag=0;
gets(s);
int a=0, b=0;
for (int i = 0; i < 1000; i++)
{
num[i] = 0;
ch[i] = '0';
}
int i = 0;
while (i < strlen(s))
{
if (in(s[i]))//如果是数字则入num
{
while (in(s[i]))
num[a] = num[a] * 10 + s[i++] - '0';//多位数的情况
a++;
continue;
}
else//不是数字
{
if (s[i] == '(') //遇到左括号直接入ch【】
ch[b++] = s[i];
else if (s[i] == ')')//遇到右括号计算
{
while (ch[b - 1] != '(')
{
num[a - 2] = A(num[a - 2], ch[b - 1], num[a - 1],&flag);
num[a - 1] = 0;
b--;//改变符号栈栈顶
a--;//改变数字栈栈顶
}
b--;
}
else {//遇到运算符
if (b == 0) //符号栈为空,直接入
ch[b++] = s[i];
else if (B(s[i], ch[b - 1]))//判断当前符号与符号栈栈顶元素的优先级,如果当前元素优先级大直接入
ch[b++] = s[i];
else //栈顶元素优先级小,进行计算
{
while (!B(s[i], ch[b - 1])) {
if (ch[b - 1] == '(')//多重括号的情况
break;
num[a - 2] = A(num[a - 2], ch[b - 1], num[a - 1],&flag);
num[a - 1] = 0;
b--;
a--;
if (b == 0)break;
}
ch[b++] = s[i];//计算完后将此符号入ch【】
}
}
}
i++;
}
while (a != 1 && b > 0)//数字栈数组中剩余两位,符号剩余一位
{
num[a - 2] = A(num[a - 2], ch[b - 1], num[a - 1],&flag);
a--;
b--;
}
if (flag == 1)
printf("ILLEGAL");
else
printf("%d", num[0]);
}