1、)#2为了算法简洁,在表达式的左边和右边虚设一个“#”,这一对“#”表示一个表达式求值完成。“(”=“)”当一对括号相遇时表示括号内已运算完成。“)”和“(”、“#”和“(”、“(”和“#”无法相继出现如果出现则表达式出现语法错误。为实现优先算法,可以使用两个工作栈,一个是OPTR,用于寄存运算符,一个是OPND,用于寄存运算数和运算结果。3. 算法基本思路 首先置操作数栈为空栈,表达式起始符为“#”为栈底元素。 依次读入表达式中的每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕(OPTR栈顶元素和当前读入的字符均为“#”)。
2、4. 求值函数EvaluateExpression实现根据算法基本思路,代码实现如下:int EvaluateExpression() int flag; char c; char x,theta; char a,b; char OP=+-*/()#; SqStack OPTR; SqStack OPND; InitStack(&OPTR); Push(&OPTR,#);OPND); flag=getNext(&c); GetTop(OPTR, &x); while(c!= | x != if(flag = 0) Push(&OPND,c); flag = getNext(& else Get
3、Top(OPTR, & switch(Precede(x, c) case :/栈顶元素优先级低 Push(&OPTR,c); flag = getNext(& break;/脱括号并接受下一字符 Pop(&OPTR,&/退栈并将运算结果入栈 OPTR, &theta);OPND,&b);a);OPND, Operate(a, theta, b); GetTop(OPTR, & GetTop(OPND, & freestack(& return c;5. Main函数实现Main函数实现void main() int c; printf(Please input one expression:
4、 c=EvaluateExpression();Result=%dn,c);结果如下图1所示:6. 源码可以直接在VS上进行编译运行。#include stdio.hstdlib.hctype.htypedef int Status;#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef char SElemType; /*放入堆栈的元素的类型*/typedef struct SElemType *base; SElemType *top; int stacksize;SqStack;/构造一个空栈Status InitStack
5、(SqStack *S) S-base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType); if(!S-base) exit (-1);top=S-base;stacksize=STACK_INIT_SIZE; return 1;void freestack(SqStack *S) free(S-base);/判断是否为空栈Status StackEmpty(SqStack S) if(S.top = S.base) else return 0;/用e返回S的顶元素Status GetTop(SqStack S, SElemType
6、*e) return -1; *e = *(S.top-1);/插入e为新的顶元素Status Push(SqStack *S, SElemType e) if(S-top - S-base) = S-stacksize)base = ( SElemType*)realloc(S-base, (S-stacksize+STACKINCREMENT)*sizeof(SElemType) ); exit(-1);top = S-base +S-stacksize;stacksize += STACKINCREMENT; *(S-top)=e;top+;/删除S的顶元素,并用e返回其值Status
7、Pop(SqStack *S, SElemType *e) if(S-top = S-top-; *e = *(S-top);/从栈底到栈顶依次对S的每个元素调用函数Visit(),一旦失败操作无效Status ListTraverse(SqStack S,Status (*visit)(SElemType) SElemType *p; p=S.base; for(p=S.base;pb0表示不可能出现的比较char Precede(char a, char b) int i,j; char pre7= /*运算符之间的优先级制作成一张表格*/ ,; switch(a) case + i=0;
8、 break;- i=1;* i=2;/ i=3;( i=4;) i=5; i=6; switch(b) j=0; j=1; j=2; j=3; j=4; j=5; j=6; return preij;/*进行实际的运算 *a,b中分别以整数的形式存放两个待运算的操作数 *theta中存放代表操作符的字符 *结果以整数的形式返回int Operate(int a, char theta, int b) int i,j,result; i=a; j=b; switch(theta) result = i + j; result = i - j; result = i * j; result =
9、i / j; return result;/*从输入缓冲区中获得下一个整数或运算符,并通过n带回到主调函数 *返回值为1表示获得的是运算符 *返回值为0表示获得的是整形操作数int getNext(char *n) *n=0; while(c=getchar()= /*跳过一个或多个空格*/isdigit(c) /*通过函数判断如果字符不是数字,那么只能是运算符*/ *n=c; do /*能执行到该条语句,说明字符是数字,此处用循环获得连续的数字*/ *n=*n*10+(c- /*把连续的数字字符转换成相对应的整数*/ c=getchar(); while(isdigit(c); /*如果下一个字符是数字,进入下一轮循环*/ ungetc(c,stdin); /*新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区*/退栈并将运算结果入栈
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1