中缀表达式求值

written on 2022-07-10

补一下普及组知识点,这次总结一下模板,希望以后能熟练地应用。

对于给定的中缀表达式,首先应将其转化为后缀。大致步骤如下:

  1. 读入字符串(中缀表达式)。

  2. 开一个新的 \(\text{int}\) 类型数组,以后一般就用 \(H\) 好了,然后开一个 \(\text{char}\) 类型的栈 \(sta\),存放的是扫描中缀表达式过程中遇到的运算符,包括 \(+,-,\times,\div,(\) 五种,然后规定优先级为 \(\text{乘除}=3,\text{加减}=2,\text{左括号}=1\)

  3. 若碰到一个左括号,直接入栈。若碰到一个右括号,栈中运算符依次弹出到 \(H\)(不含左括号),直到与之匹配的左括号。若碰到其他运算符,将所有大于等于它的优先级的都弹出,然后再压入这个运算符。

  4. 若碰到数字,直接放入 \(H\) 数组。

  5. 最后将栈中剩下的运算符全部放入 \(H\) 数组。

然后就是后缀表达式求值的事情了,这时只要每次碰上一个运算符,就取出两个栈顶(区分原栈,命名为 \(T\))元素做相应运算然后放回栈顶即可,最后栈中剩下的唯一一个元素也就是答案。

我的代码中的 \(\text{Change}\) 演示的是中缀转后缀的过程。

char a[N];
int Go(char x)
{
	if(x=='*') return -1;
	if(x=='-') return -2;
	if(x=='+') return -3;
}
int level(char x)
{
	if(x=='(') return 1;
	if(x=='+'||x=='-') return 2;
	if(x=='*') return 3;
}
int top,H[N];
char sta[N];
void Change()
{
	int len=strlen(a+1),x=0;
	for(int i=1;i<=len;i++)
	{
		if(isdigit(a[i]))
		{
			x=(x*10+a[i]-'0');
			if(!isdigit(a[i+1])) H[++H[0]]=x,x=0;
		}
		else if(a[i]=='x') H[++H[0]]=-4;
		else if(a[i]=='(') sta[++top]=a[i];
		else if(a[i]==')')
		{
			while(top&&sta[top]!='(') H[++H[0]]=Go(sta[top--]);
			top--;
		}
		else
		{
			while(top&&level(sta[top])>=level(a[i])) H[++H[0]]=Go(sta[top--]);
			sta[++top]=a[i];
		}
	}
	while(top) H[++H[0]]=Go(sta[top--]);
//	for(int i=1;i<=H[0];i++) printf("%d ",H[i]);
}
posted @ 2022-07-31 22:09  Freshair_qprt  阅读(90)  评论(0编辑  收藏  举报