pta-表达式求值

7-2 表达式求值 (10 分)

给定一个中缀表达式,请编写程序计算该表达式的值。表达式包含+、-、*、\、(、),所有运算均为二元运算,操作数均为正整数,但可能不止一位,不超过5位。运算结果为整数,值域为[−2 ^31,2 ^31)。除法运算结果若为小数则进行截尾取整。若除法运算中除数为0,则输出ILLEGAL。
  1. 输入格式:
    输入为一个字符串,表示中缀表达式。
  2. 输出格式:
    输出为一个整数,为表达式的值;或者为一个字符串ILLEGAL。
  3. 输入样例1:
    5+(10*2)-6
  4. 输出样例1:
    19
  5. 输入样例2:
    8*(999+1)
  6. 输出样例2:
    8000
  7. 输入样例3:
    1+5/(1-1)
  8. 输出样例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]);
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tom里的同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值