利用栈实现表达式求值

学号 E22214006    专业 软件工程    姓名 郭晨坡

实验日期   2023.5.25      教师签字     成绩

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef char ElemType;

typedef int Status;

#define LIST_INIT_SIZE 100

#define LISTINCREMENT 10

#define OK 1

#define ERROR 10

//栈的顺序存储表示

typedef struct //参考书Pg. 46

{

ElemType *base;//栈底指针

ElemType *top;//栈顶指针

int stacksize;//当前分配的存储容量

}SqStack;

Status InitSqStack(SqStack &S)

{//请补充你的代码:初始构造一个空栈S。

S.base =new ElemType[LIST_INIT_SIZE];

if(!S.base ) exit(false);

S.top =S.base ;

S.stacksize =LIST_INIT_SIZE;

return OK;

}

Status DestroySqStack(SqStack &S)

{//请补充你的代码:销毁一个栈S

if(S.base )

{

delete S.base ;

S.base =NULL;

S.top =NULL;

S.stacksize =0;

}

return OK;

}

Status GetTop(SqStack S,ElemType & e)

{//请补充你的代码:若栈非空,则用e返回S的栈顶元素,并返回OK,否者返回ERROR

if(S.base !=S.top )

{

e=*(S.top-1);

return OK;

}

else

return ERROR;

}

Status Push(SqStack &S,ElemType e)

{//请补充你的代码:插入e为新的栈顶元素

if(S.top -S.base ==S.stacksize ) return ERROR;//栈满

*S.top =e;

S.top++;

return OK;

}

Status Pop(SqStack &S,ElemType &e)

{//请补充你的代码:若栈非空,则删除S的栈顶元素,用e返回其值,并返回OK,否者返回ERROR

if(S.top!=S.base)

{

e=*--S.top;

return OK;

}

else

return ERROR;

}

Status In(ElemType e)//判断读入字符是否为运算符

{

if(e=='+'||e=='-'||e=='*'||e=='/'||e=='('||e==')'||e=='#')

return OK;

else

return 0;

}

ElemType Gettop(SqStack S)//只取栈顶元素

{

if(S.top!=S.base  )

return *(S.top-1);

}

ElemType Precede(ElemType a,ElemType b)//判定运算符栈的栈顶元素与读入的运算符之间优先关系

{

int i,j;

ElemType OP[7]= {'+','-','*','/','(',')','#'};

ElemType CMP[7][7]={

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

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

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

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

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

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

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

    for(i=0;i<7;i++)

    {

     if(OP[i]==a)

     break;

}

 for(j=0;j<7;j++)

    {

     if(OP[j]==b)

     break;

}

return CMP[i][j];

}

ElemType Operate(ElemType a,ElemType b,ElemType c)//进行运算

{

ElemType Y;

a=a-48;

c=c-48;

if(b=='+') Y=a+c;

if(b=='-') Y=a-c;

if(b=='*') Y=a*c;

if(b=='/') Y=a/c;

return Y+48;

}

Status pf(SqStack A,SqStack B)//输出运算符栈和运算数栈的数据

{

int i=0,j;

ElemType T[10]={'0','0','0','0','0','0','0','0','0','0'};

Status Y[10]={0,0,0,0,0,0,0,0,0,0};

while((A.top-i)!=A.base)

{

T[i]=*(A.top-i-1);

i++;

}

i=0;

while((B.top-i)!=B.base)

{

Y[i]=*(B.top-i-1);

i++;

}

printf("  ");

for(j=9;j>=0;j--)

{

if(T[j]!='0')

printf("%c ",T[j]);

}

printf("   ");

for(j=9;j>=0;j--)

{

if(Y[j]!=0)

printf("%d ",Y[j]-48);

}

printf("   ");

}

//主函数,参考Pg 53

int main(int argc,char* argv[])

{

//输出你的姓名和学号

printf("\n%s, %s\n",name,id);

ElemType OP[7]= {'+','-','*','/','(',')','#'};

ElemType STR[15]={'#','3','*','(','5','-','1',')','+','2','/','2','-','3','#'};

//请按照表3.1填入数组元素

ElemType CMP[7][7]={

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

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

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

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

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

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

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

//请补充你的代码: 屏幕显示 STR: #3*(5-1)+2/2-3#

int i,k,l;

for(i=0;i<15;i++)

{

printf("%c",STR[i]);

}

printf("\n");

SqStack OPTR;//运算符栈

SqStack OPND;//运算数栈

//初始化 OPTR 和 OPND

InitSqStack(OPTR);

InitSqStack(OPND);

//请补充你的代码:利用栈实现这个表达式值 Str,并且在屏幕上显示这个表达式最终计算结果,

//并且把中间结果信息(如例3-1,OPTR栈,OPND栈,输入字符,主要操作)显示在屏幕上

printf("步骤  OPTR栈 OPND栈 读入字符 主要操作\n");

i=0;

Push(OPTR,STR[i]);

k=1;

printf("步骤%d",k);

pf(OPTR,OPND);

i++;

for(l=i;l<15;l++)

{

printf("%c",STR[l]);

}

printf("   ");

k=2;

ElemType a,b,c,y,j;

while(STR[i]!='#'||Gettop(OPTR)!='#')

{

if(!In(STR[i]))

{

printf("Push(OPND,%c);",STR[i]);

printf("\n");

printf("步骤%d",k);

Push(OPND,STR[i]);

i++;k++;

pf(OPTR,OPND);

for(l=i;l<15;l++)

{

printf("%c",STR[l]);

}

printf("   ");

}

else

{

switch(Precede(Gettop(OPTR),STR[i]))

{

case'<':

Push(OPTR,STR[i]);

printf("Push(OPTR,%c);",STR[i]);

printf("\n");

printf("步骤%d",k);

i++;k++;

pf(OPTR,OPND);

for(l=i;l<15;l++)

{

printf("%c",STR[l]);

}

printf("   ");

break;

case'>':

Pop(OPTR,b);

Pop(OPND,c);

Pop(OPND,a);

printf("Push(OPND,Operate(%c,%c,%c))",a,b,c);

printf("\n");

Push(OPND,Operate(a,b,c));

printf("步骤%d",k);k++;

pf(OPTR,OPND);

for(l=i;l<15;l++)

{

printf("%c",STR[l]);

}

printf("   ");

break;

case'=':

Pop(OPTR,y);

printf("Pop(OPTR,%c)",y);

printf("\n");

printf("步骤%d",k);

pf(OPTR,OPND);

i++;k++;

for(l=i;l<15;l++)

{

printf("%c",STR[l]);

}

printf("   ");

break;

}

}

}

printf("\n");

GetTop(OPND,j);

printf("最终结果:%d",j-48);

//请补充你的代码:释放OPTR,OPND

DestroySqStack(OPTR);

DestroySqStack(OPND);

return 1;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我睁眼了呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值