用栈求算术表达式的值

  • 题目:1 将中缀表达式转换为后缀表达式
  • 2 求后缀表达式的值
#include<stdio.h>

#define MaxSize 100

struct
{
	char data[MaxSize];
	int top;  //栈顶指针
}op;  //定义运算符栈

struct
{
	float data[MaxSize];
	int top;
}st;  //定义数值栈

void trans(char exp[],char postexp[])
{
	int i = 0;
	int j = 0;
	char ch;
	op.top = -1;  //栈顶指针初始化为-1
	ch = exp[i];
	i++;

	while (ch != '\0')
	{
		switch (ch)
		{
		case '(':  //判定为左括号 直接入栈
			op.top++;
			op.data[op.top] = ch;
			break;
		case ')':
			while (op.data[op.top] != '(')
			{
				postexp[j] = op.data[op.top];
				op.top--;
				j++;
			}
			op.top--;  //左括号也出栈 但不输出
			break;
		case '+':
		case '-':
			//为 + 或者 - 时候,优先级不大于栈顶任何运算符的优先级 直到 )
			while (op.top != -1 && op.data[op.top] != '(')
			{
				postexp[j] = op.data[op.top];
				j++;
				op.top--;
			}
			op.top++;
			op.data[op.top] = ch;
			break;
		case '*':
		case '/':
			//为 * 或者是 / 时, 其优先级不大于栈顶为 * 或者为 /的优先级 直到 (
			while (op.top != -1 && op.data[op.top] != '('
				&& (op.data[op.top] == '*' || op.data[op.top] == '/'))
			{
				//将栈顶运算符弹出并输出
				postexp[j] = op.data[op.top];
				j++;
				op.top--;
			}
			//该运算符的优先级大于栈顶运算符的优先级 直接压栈
			op.top++;
			op.data[op.top] = ch;
			break;
		case ' ':  //过滤掉空格
			break;  
		default:
			while (ch >= '0' && ch <= '9') //判定为数字
			{
				postexp[j] = ch;
				j++;
				ch = exp[i];
				i++;
			}
			i--;
			postexp[j] = '#';  //用#标识一个数值串结束
			j++;
			break;
		}
		ch = exp[i];
		i++;
	}

	while (op.top != -1)  //此时exp扫描完毕 栈不空时出栈并存放到postexp
	{
		postexp[j] = op.data[op.top];
		j++;
		op.top--;
	}
	postexp[j] = '\0';  //添加结束标识符
}

//后缀表达式的求值过程
float Compvalue(char postexp[])
{
	char ch;
	float d;
	int i = 0;
	ch = postexp[i];
	i++;
	st.top = -1;
	while (ch != '\0')
	{
		switch (ch)
		{
		case '+':
			st.data[st.top - 1] = st.data[st.top - 1] + st.data[st.top];
			st.top = st.top - 1;
			break;
		case '-':
			st.data[st.top - 1] = st.data[st.top - 1] - st.data[st.top];
			st.top = st.top - 1;
			break;
		case '*':
			st.data[st.top - 1] = st.data[st.top] * st.data[st.top - 1];
			st.top = st.top - 1;
			break;
		case '/':
			if (st.data[st.top] != 0)
			{
				st.data[st.top - 1] = st.data[st.top - 1] / st.data[st.top];
				st.top = st.top - 1;
			}
			else
			{
				printf("除数为0.\n");
				return 0.0;
			}
			break;
		default:
			d = 0;
			while (ch >= '0' && ch <= '9')
			{
				d = d * 10 + ch - '0';
				ch = postexp[i];
				i++;
			}
			st.top++;
			st.data[st.top] = d;
			break;
		}
		ch = postexp[i];
		i++;
	}
	return st.data[st.top];
}

int main()
{
	int i = 0;
	char exp[] = {"(2*2)*1+3*2/1"};
	char postexp[MaxSize];
	trans(exp,postexp);
	while (postexp[i] != '\0')
	{
		printf("%c",postexp[i]);
		i++;
	}
	printf("\n");
	printf("运算结果为:%f.\n", Compvalue(postexp));
	system("pause");
	return 0;
}

后缀表达式求值如下:

while(从postexp中间读取字符ch,ch != '\0')
{
    若ch为数字,将后继的所有数字构成一个整数存放到数值栈st中
	若ch为 "+",则从数值栈st中退栈两个运算数,相加后进栈st中
	若ch为 "-",则从数值栈st中退栈两个运算数,相减后进栈st中
	若ch为 "*",则从数值栈st中退栈两个运算数,相乘后进栈st中
	若ch为 "/",则从数值栈st中退栈两个运算数,相除后进栈st中(若除数为0,则提示错误)
}
  • 运行结果

  • 参考资料:
    1 《新编数据结构习题与解析》

posted @ 2019-08-26 21:16  尚修能的技术博客  阅读(873)  评论(0编辑  收藏  举报