数据结构笔记之十一栈的应用之表达式求值实现.docx

上传人:b****4 文档编号:5192596 上传时间:2022-12-13 格式:DOCX 页数:12 大小:48.27KB
下载 相关 举报
数据结构笔记之十一栈的应用之表达式求值实现.docx_第1页
第1页 / 共12页
数据结构笔记之十一栈的应用之表达式求值实现.docx_第2页
第2页 / 共12页
数据结构笔记之十一栈的应用之表达式求值实现.docx_第3页
第3页 / 共12页
数据结构笔记之十一栈的应用之表达式求值实现.docx_第4页
第4页 / 共12页
数据结构笔记之十一栈的应用之表达式求值实现.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

数据结构笔记之十一栈的应用之表达式求值实现.docx

《数据结构笔记之十一栈的应用之表达式求值实现.docx》由会员分享,可在线阅读,更多相关《数据结构笔记之十一栈的应用之表达式求值实现.docx(12页珍藏版)》请在冰豆网上搜索。

数据结构笔记之十一栈的应用之表达式求值实现.docx

数据结构笔记之十一栈的应用之表达式求值实现

11、蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现

本篇名言:

“人生不售来回票,一旦动身,绝不能复返。

继续栈应用实现,这次是来看下表达式求值的栈实现。

1.表达式求值

表达式求值是设计语言编译中的一个基本问题,它的实现是栈应用的又一个典型例子。

任何一个表达式都是由操作数(Operand)、运算符(operator)和界限符(delimiter)组成。

操作数可以是常数也可以是变量或变量的标识符。

运算符可以分为算术运算符、关系运算符和逻辑运算符三类。

界限符有左右括号和表达式结束符。

几个算术四则运算的规则:

⏹先乘除,后加减;

⏹从左算到右

⏹先括号内,后括号外

此处实现,假定不出现语法错误,否则过于复杂,蛤蟆也不能理解了。

2.运算符优先级

对于连个相继出现的操作符θ1和θ2 有三种关系:

大于、等于和小于。

由此可以列出“+-*/”之间的优先级。

如下表:

 

+

-

*

/

#

+

>

>

<

<

<

>

>

-

>

>

<

<

<

>

>

*

>

>

>

>

<

>

>

/

>

>

>

>

<

>

>

<

<

<

<

<

=

 

>

>

>

>

 

>

>

#

<

<

<

<

<

 

=

加减乘除优先性都低于“(”但是高于“)”,由运算从左到右可知,当θ1=θ2 ,令θ1>θ2

为了算法简洁,在表达式的左边和右边虚设一个“#”,这一对“#”表示一个表达式求值完成。

“(”=“)”当一对括号相遇时表示括号内已运算完成。

“)”和“(”、“#”和“(”、“(”和“#”无法相继出现如果出现则表达式出现语法错误。

为实现优先算法,可以使用两个工作栈,一个是OPTR,用于寄存运算符,一个是OPND,用于寄存运算数和运算结果。

3.算法基本思路

●首先置操作数栈为空栈,表达式起始符为“#”为栈底元素。

●依次读入表达式中的每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕(OPTR栈顶元素和当前读入的字符均为“#”)。

4.求值函数EvaluateExpression实现

根据算法基本思路,代码实现如下:

intEvaluateExpression(){

intflag;

charc;

charx,theta;

chara,b;

charOP[]="+-*/()#";

SqStackOPTR;

SqStackOPND;

InitStack(&OPTR);

Push(&OPTR,'#');

InitStack(&OPND);

flag=getNext(&c);

GetTop(OPTR,&x);

while(c!

='#'||x!

='#')

{

if(flag==0)

{

Push(&OPND,c);

flag=getNext(&c);

}

else

{

GetTop(OPTR,&x);

switch(Precede(x,c))

{

case'<':

//栈顶元素优先级低

Push(&OPTR,c);

flag=getNext(&c);

break;

case'=':

//脱括号并接受下一字符

Pop(&OPTR,&x);

flag=getNext(&c);

break;

case'>':

//退栈并将运算结果入栈

Pop(&OPTR,&theta);

Pop(&OPND,&b);

Pop(&OPND,&a);

Push(&OPND,Operate(a,theta,b));

break;

}

}

GetTop(OPTR,&x);

}

GetTop(OPND,&c);

freestack(&OPTR);

freestack(&OPND);

returnc;

}

5.Main函数实现

Main函数实现

voidmain(){

intc;

printf("Pleaseinputoneexpression:

");

c=EvaluateExpression();

printf("Result=%d\n",c);

}

结果如下图1所示:

6.源码

可以直接在VS上进行编译运行。

#include"stdio.h"

#include"stdlib.h"

#include"ctype.h"

typedefintStatus;

#defineSTACK_INIT_SIZE100

#defineSTACKINCREMENT10

typedefcharSElemType;/*放入堆栈的元素的类型*/

typedefstruct{

SElemType*base;

SElemType*top;

intstacksize;

}SqStack;

//构造一个空栈

StatusInitStack(SqStack*S){

S->base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

if(!

S->base)

exit(-1);

S->top=S->base;

S->stacksize=STACK_INIT_SIZE;

return1;

}

voidfreestack(SqStack*S){

free(S->base);

}

//判断是否为空栈

StatusStackEmpty(SqStackS){

if(S.top==S.base)

return1;

else

return0;

}

//用e返回S的顶元素

StatusGetTop(SqStackS,SElemType*e){

if(S.top==S.base)

return-1;

*e=*(S.top-1);

return1;

}

//插入e为新的顶元素

StatusPush(SqStack*S,SElemTypee){

if((S->top-S->base)>=S->stacksize){

S->base=(

SElemType*)realloc(S->base,

(S->stacksize+STACKINCREMENT)*sizeof(SElemType)

);

if(!

S->base)

exit(-1);

S->top=S->base+S->stacksize;

S->stacksize+=STACKINCREMENT;

}

*(S->top)=e;

S->top++;

return1;

}

//删除S的顶元素,并用e返回其值

StatusPop(SqStack*S,SElemType*e){

if(S->top==S->base)

return-1;

S->top--;

*e=*(S->top);

return1;

}

//从栈底到栈顶依次对S的每个元素调用函数Visit(),一旦失败操作无效

StatusListTraverse(SqStackS,Status(*visit)(SElemType)){

SElemType*p;

p=S.base;

for(p=S.base;p

(*visit)(*p);

return1;

}

//输出元素e

Statusoutput(SElemTypee){

printf("%d",e);

return1;

}

 

/*计算整数表达式的值

*表达式必须以#结束

*表达式中可以出现多位数字,

*表达式中可以出现空格

*运算符包括+,-,*,/,(,)

*运算结果可以是多位整数,并以整数的形式返回

*/

 

/*判断输入的某个字符是否是运算符

*c表示输入的字符

*op数组中存放系统能识别的运算符

*/

Statusin(charc,charop[]){

char*p;

p=op;

while(*p!

='\0'){

if(c==*p)

return1;

p++;

}

return0;

}

/*比较两个运算符的优先级

*a,b中存放待比较的运算符

*'>'表示a>b

*'0'表示不可能出现的比较

*/

charPrecede(chara,charb){

inti,j;

charpre[][7]={

/*运算符之间的优先级制作成一张表格*/

{'>','>','<','<','<','>','>'},

{'>','>','<','<','<','>','>'},

{'>','>','>','>','<','>','>'},

{'>','>','>','>','<','>','>'},

{'<','<','<','<','<','=','0'},

{'>','>','>','>','0','>','>'},

{'<','<','<','<','<','0','='}};

switch(a){

case'+':

i=0;break;

case'-':

i=1;break;

case'*':

i=2;break;

case'/':

i=3;break;

case'(':

i=4;break;

case')':

i=5;break;

case'#':

i=6;break;

}

switch(b){

case'+':

j=0;break;

case'-':

j=1;break;

case'*':

j=2;break;

case'/':

j=3;break;

case'(':

j=4;break;

case')':

j=5;break;

case'#':

j=6;break;

}

returnpre[i][j];

}

/*进行实际的运算

*a,b中分别以整数的形式存放两个待运算的操作数

*theta中存放代表操作符的字符

*结果以整数的形式返回

*/

intOperate(inta,chartheta,intb){

inti,j,result;

i=a;

j=b;

switch(theta){

case'+':

result=i+j;break;

case'-':

result=i-j;break;

case'*':

result=i*j;break;

case'/':

result=i/j;break;

}

returnresult;

}

/*从输入缓冲区中获得下一个整数或运算符,并通过n带回到主调函数

*返回值为1表示获得的是运算符

*返回值为0表示获得的是整形操作数

*/

intgetNext(char*n){

charc;

*n=0;

while((c=getchar())=='');/*跳过一个或多个空格*/

if(!

isdigit(c)){/*通过函数判断如果字符不是数字,那么只能是运算符*/

*n=c;

return1;

}

do{/*能执行到该条语句,说明字符是数字,此处用循环获得连续的数字*/

*n=*n*10+(c-'0');/*把连续的数字字符转换成相对应的整数*/

c=getchar();

}while(isdigit(c));/*如果下一个字符是数字,进入下一轮循环*/

ungetc(c,stdin);/*新读入的字符不是数字,可能是运算符,为了不影响下次读入,把该字符放回到输入缓冲区*/

return0;

}

intEvaluateExpression(){

 

intflag;

charc;

charx,theta;

chara,b;

charOP[]="+-*/()#";

SqStackOPTR;

SqStackOPND;

InitStack(&OPTR);

Push(&OPTR,'#');

InitStack(&OPND);

flag=getNext(&c);

GetTop(OPTR,&x);

while(c!

='#'||x!

='#')

{

if(flag==0)

{

Push(&OPND,c);

flag=getNext(&c);

}

else

{

GetTop(OPTR,&x);

switch(Precede(x,c))

{

case'<':

//栈顶元素优先级低

Push(&OPTR,c);

flag=getNext(&c);

break;

case'=':

//脱括号并接受下一字符

Pop(&OPTR,&x);

flag=getNext(&c);

break;

case'>':

//退栈并将运算结果入栈

Pop(&OPTR,&theta);

Pop(&OPND,&b);

Pop(&OPND,&a);

Push(&OPND,Operate(a,theta,b));

break;

}

}

GetTop(OPTR,&x);

}

GetTop(OPND,&c);

freestack(&OPTR);

freestack(&OPND);

returnc;

}

voidmain(){

intc;

printf("Pleaseinputoneexpression:

");

c=EvaluateExpression();

printf("Result=%d\n",c);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1