请使用链栈实现简单算术表达式求值的功能。
输入:
任意简单算数表达式(仅包含“+”,“-”,“*”,“/”,“(”,“)”),并以“#”为结尾
输出:
算术表达式的值
输入示例1
1+3*(4-2)+5#
输出示例1
12
输入示例2
2*(9-4)+5*(7-5)#
输出示例2
20
[算法步骤]
① 初始化OPTR栈和OPND栈, 将表达式起始符'#'压入OPTR栈.
② 扫描表达式, 读入第一个字符ch, 如果表达式没有扫描完毕至'#'或OPTR栈的栈顶元素不为'#'时, 则循环执行以下操作:
● 若ch不是运算符, 则压入OPND栈, 读入下一字符ch;
● 若ch是运算符, 则根据OPTR栈的栈顶元素和ch的优先级比较结果, 做不同的处理:
▲ 若是小于, 则ch压入OPTR栈, 读入下一字符ch;
▲ 若是大于, 则弹出OPTR栈的栈顶运算符, 并从OPND栈中弹出两个操作数, 进行相应运算, 结果压入OPND栈中;
▲ 若是等于, 则OPTR栈的栈顶元素是'('且ch是')', 这时弹出OPTR栈顶的'(', 相当于括号匹配成功, 然后读入下一字符ch.
③ OPND栈的栈顶元素即为表达式求值结果, 返回此元素.
#include<stdio.h>
#include<stdlib.h>
struct Node/* 链栈OPTR结点 */
{
char c;
struct Node *next;
};
struct Node_OPND/* 链栈OPND结点 */
{
short n;
struct Node_OPND *next;
};
/* */
void InitLinkStack(struct Node* &OPTR, struct Node_OPND* &OPND);
void Push(struct Node* &p, char c);
void Push2(struct Node_OPND* &p, short c);
void Pop(struct Node* &s, char &c);
void Pop2(struct Node_OPND* &s, short &c);
char GetTop(struct Node* &s);
short GetTop2(struct Node_OPND* &s);
void Traversal(struct Node* &p);
void Traversal2(struct Node_OPND* &s);
short IsOPTR(char c);
char Compare(char x, char y);
short Operate(short a, char theta, short b);
short EvaluateExpression(struct Node* &OPTR, struct Node_OPND* &OPND);
/* */
int main()
{
struct Node *OPTR;/* OPTR栈用于寄存运算符 */
struct Node_OPND *OPND;/* OPND栈用于寄存操作数或运算结果 */
printf("%hd\n", EvaluateExpression(OPTR, OPND));
return 0;
}
/* */
short EvaluateExpression(struct Node* &OPTR, struct Node_OPND* &OPND)
{
char ch;
char theta;
char x;
short a;
short b;
InitLinkStack(OPTR, OPND);/* 初始化链栈 */
/* 经测试, 两种链栈的基本操作没问题 */
ch = getchar();
while(ch != '#' || GetTop(OPTR) != '#')
{
if(IsOPTR(ch) == 0)
{
/* ch不是运算符(即数字字符) */
Push2(OPND, ch - '0');/* 进OPND栈 */