表达式求值

表达式有多种表示方式
例如: Exp = a * b + (c * d / e) * f
前缀式: + * a b * * c / d e f
中缀式: a * b + c * d / e * f
后缀式: a b * c d e / * f * +

得到后缀表达式后可以用栈得到结果

如何得到后缀表达式?

每个运算符的运算次序要由它之后的一个运算符来定,在后缀式中,优先数高的运算符领先于优先数低的运算符。

当前优先级较低的运算符出现后,相邻的优先级较高的运算符的运算就可以确定了

从原表达式求得后缀式的步骤:

设立运算符栈,预置栈底元素为“#”(设表达式的结束符为“#”);

若当前字符是操作数,则直接发送给后缀式;

若当前运算符的优先数高于栈顶运算符,则进栈;否则,退出栈顶运算符发送给后缀式。
“(” 对它之前后的运算符起隔离作用
“)”可视为自相应左括弧开始的表达式的结束符

void transform(char suffix[ ], char exp[ ] ) 
{
	// 从合法的表达式字符串exp求得其相应的后缀式字符串suffix,
	// precede(a,b)判别算符法的优先程度,当a的优先数≥b 的优先数时,返回 1,否则返回0
	InitStack(S);      Push(S, '#');                   // 预设运算符栈的栈底元素为'#'
	p = exp;      ch = *p;       k=0;
	while (!StackEmpty(S)) 
	{
		if (!OpMember(ch))   Suffix[k++] = ch;       // 操作数直接发送给后缀式
		else 
		{
			switch (ch) 
			{
				case '(' : Push(S, ch); break;            // 左括弧一律入栈
				case ')' : 
					{
						Pop(S, c);
						while (c!= '(' )            // 自栈顶至左括弧之前的运算符发送给后缀式
						{
							Suffix[k++] = c;  Pop(S, c) 
						}
						break; 
					}
				default : 
					{
						while( Gettop(S, c) && ( precede(c,ch)) ) 
						{              
							Suffix[k++] =c;  Pop(S, c); 
						}  // 将栈中所有优先数不小于当前运算符优先数的运算符发送给后缀式
						if ( ch!= '#' )  Push( S, ch);           // 优先数大于栈顶的运算符入栈
						break;
					} 
			}
		}
		if ( ch!= '#' ) ch = *++p;  
	} 
	Suffix[k] = '\0' ;                             // 添加字符串的结束符
}

题目
https://www.luogu.com.cn/problem/P1449
https://www.luogu.com.cn/problem/P1981

posted @ 2023-08-10 14:25  wljss  阅读(29)  评论(0编辑  收藏  举报