DSOJ 中缀表达式求值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xhf0374/article/details/50360576

题目链接


#include<stdio.h>		//中缀表达式求值
#include<string.h>
#include<stdlib.h>
#define MAX 600

char Infix[MAX];
char Postfix[2 * MAX];		//在操作数及操作符之后都加一个空格

int StrToInt(char *s, int begin, int end)	//字符串转化为int型数据,处理操作数为多位数的情形
{
	int i, sum = 0;
	for (i = begin; i < end; i++)
		sum = sum * 10 + s[i] - '0';
	return sum;
}

void Transfer()		//将中缀表达式转化为后缀表达式
{
	char stack[MAX];
	int top = -1, i, j;
	int InfixLen = strlen(Infix);
	for (i = 0, j = 0; i < InfixLen; i++)
	{
		switch (Infix[i])
		{
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			Postfix[j++] = Infix[i];
			if (i + 1 < InfixLen&&!(Infix[i + 1] >= '0'&&Infix[i + 1] <= '9'))	//下一位不是数字,则在其后补空格' '
			{
				Postfix[j++] = ' ';
			}
			if (i + 1 == InfixLen) Postfix[j++] = ' ';			//最后一位数字之后加空格
			break;
		case '+':
		case '-':
			if (top == -1)
			{
				stack[++top] = Infix[i];
			}
			else
			{
				while (top > -1 && stack[top] != '(')		//弹栈直至栈空或遇到左括号
				{
					Postfix[j++] = stack[top--];
					Postfix[j++] = ' ';						//操作符后补空格
				}
				stack[++top] = Infix[i];		//当前操作符入栈
			}
			break;
		case '*':
		case '/':
			if (top == -1)
			{
				stack[++top] = Infix[i];
			}
			else
			{
				while (top > -1 && stack[top] != '('&&stack[top] != '+'&&stack[top] != '-')
				//弹栈直至遇到比当前操作符优先级低的操作符或栈空或左括号
				{
					Postfix[j++] = stack[top--];
					Postfix[j++] = ' ';
				}
				stack[++top] = Infix[i];
			}
			break;
		case '(':
			stack[++top] = Infix[i];			//左括号直接入栈
			break;
		case ')':
			while (top > -1 && stack[top] != '(')	//遇到右括号将栈中操作符出栈直至遇到左括号
			{
				Postfix[j++] = stack[top--];
				Postfix[j++] = ' ';
			}
			if (top == -1)
			{
				printf("右括号多余,输入的表达式不合法\n");
				exit(0);
			}
			else
				top--;		//将左括号出栈
			break;
		default:
			printf("输入的中缀表达式中有非法的字符出现\n");
			exit(0);
		}
	}
	while (top > -1 && stack[top] != '(')		//栈中剩余操作符出栈
	{
		Postfix[j++] = stack[top--];
		Postfix[j++] = ' ';
	}
	Postfix[--j] = '\0';						//!重要!将Postfix的最后一位的空格赋值为'\0',以示字符串结尾
	if (top > -1 && stack[top] == '(')
	{
		printf("左括号多余,输入的表达式不合法\n");
		exit(0);
	}
}


int Compute(char op, int num1, int num2)			//计算num1(op)num2
{
	switch (op)
	{
	case '+':
		return (num1 + num2);
		break;
	case '-':
		return (num1 - num2);
		break;
	case '*':
		return (num1 * num2);
		break;
	case '/':
		if (num2 == 0)
		{
			printf("0不能做除数,非法!\n");
			exit(0);
		}
		return (num1 / num2);
		break;
	}
}

int Calculator()			//计算后缀表达式的值
{
	int stack[MAX];
	int top = -1;
	int PostfixLen, i, begin, end;
	int num1, num2;
	PostfixLen = strlen(Postfix);
	for (i = 0; i < PostfixLen; i++)
	{
		if (Postfix[i] >= '0'&&Postfix[i] <= '9')
		{
			begin = i;
			while (Postfix[i] >= '0'&&Postfix[i] <= '9')
				i++;
			end = i;			//此时的i为Postfix中空格的地址,执行下一次循环i++刚好跳过空格
			stack[++top] = StrToInt(Postfix, begin, end);
		}
		else
		{
			if (top > -1) num2 = stack[top--];					//弹栈出操作数2
			else printf("ERROR!\n");
			if (top > -1) num1 = stack[top--];					//弹栈出操作数1
			else printf("ERROR!\n");
			stack[++top] = Compute(Postfix[i], num1, num2);		//将结果入栈
			i++;				//此时为空格地址
		}
	}
	return stack[top];
}


int main()
{
	int n;
	scanf("%d", &n);
	while (n--)
	{
		scanf("%s", Infix);
		Transfer();
//		puts(Postfix);
		printf("%d\n", Calculator());
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xhf0374/article/details/50360576