2表达式求值.docx
《2表达式求值.docx》由会员分享,可在线阅读,更多相关《2表达式求值.docx(11页珍藏版)》请在冰豆网上搜索。
2表达式求值
一、实验目的和要求
1、理解栈的原理
2、把自己使用的栈结构明确的表达出来
3、基本上实现每个实验题目的要求
二、实验内容和原理
1、简单表达式求值
三、软、硬件环境
硬件:
Pentium(R)Dual-coreCPUE5300@2.60Hz
1.99GB
软件:
windowsXP
C++程序设计与试验系统
四、实验步骤
一、建立运算符栈和数据栈的结构
二、建立预算符栈和数据栈
三、运算符优先级比较
四、在栈中插入元素
五、从栈中获取元素,取出某个元素后将其从栈中删除
六、实现+、—、*、/等运算
七、主函数,并包含实现多位数且含小数的运算
#include
#include
#include
#defineinit_size20
#defineincrement10
typedefstruct{
char*base;
char*top;
intstack_size;
}sqstack;//运算符栈的结构体
typedefstruct{
double*base;
double*top;
intstack_size;
}sqstack2;//数据栈的结构体
/*建立栈的函数*/
voidinitOPTR(sqstack&sq)
{
sq.base=(char*)malloc(init_size*sizeof(char));
sq.top=sq.base;
sq.stack_size=init_size;
}
voidinitOPND(sqstack2&sq)
{
sq.base=(double*)malloc(init_size*sizeof(double));
sq.top=sq.base;
sq.stack_size=init_size;
}
/*比较不同算术运算符的优先级*/
charprecede(chara,charb)
{
charc;
switch(a)
{
case'+':
switch(b)
{
case'+':
c='>';break;
case'-':
c='>';break;
case'*':
c='<';break;
case'/':
c='<';break;
case'(':
c='<';break;
case')':
c='>';break;
case'#':
c='>';break;
};break;
case'-':
switch(b)
{
case'+':
c='>';break;
case'-':
c='>';break;
case'*':
c='<';break;
case'/':
c='<';break;
case'(':
c='<';break;
case')':
c='>';break;
case'#':
c='>';break;
};break;
case'*':
switch(b)
{
case'+':
c='>';break;
case'-':
c='>';break;
case'*':
c='>';break;
case'/':
c='>';break;
case'(':
c='<';break;
case')':
c='>';break;
case'#':
c='>';break;
};break;
case'/':
switch(b)
{
case'+':
c='>';break;
case'-':
c='>';break;
case'*':
c='>';break;
case'/':
c='>';break;
case'(':
c='<';break;
case')':
c='>';break;
case'#':
c='>';break;
};break;
case'(':
switch(b)
{
case'+':
c='<';break;
case'-':
c='<';break;
case'*':
c='<';break;
case'/':
c='<';break;
case'(':
c='<';break;
case')':
c='=';break;
case'#':
c='';break;
};break;
case')':
switch(b)
{
case'+':
c='>';break;
case'-':
c='>';break;
case'*':
c='>';break;
case'/':
c='>';break;
case'(':
c='';break;
case')':
c='>';break;
case'#':
c='>';break;
};break;
case'#':
switch(b)
{
case'+':
c='<';break;
case'-':
c='<';break;
case'*':
c='<';break;
case'/':
c='<';break;
case'(':
c='<';break;
case')':
c='<';break;
case'#':
c='=';break;
};break;
}
returnc;
}
/*在栈中插入元素*/
voidPushOPTR(sqstack&sq1,charc)
{
if(sq1.top-sq1.base>=sq1.stack_size)
{
//检验内存是否分配成功
sq1.base=(char*)realloc(sq1.base,(sq1.stack_size+increment)*sizeof(char));
if(!
sq1.base)
exit(0);
sq1.top=sq1.base+sq1.stack_size;
}
*(sq1.top)=c;
sq1.top++;
}
voidPushOPND(sqstack2&sq1,doublec)
{
if(sq1.top-sq1.base>=sq1.stack_size)
{
sq1.base=(double*)realloc(sq1.base,(sq1.stack_size+increment)*sizeof(double));
if(!
sq1.base)exit(0);
sq1.top=sq1.base+sq1.stack_size;
}
*(sq1.top)=c;
sq1.top++;
}
/*在栈中获得栈顶元素*/
charGetTopOPTR(sqstack&sq1)
{
if(sq1.top==sq1.base)exit(0);
charc=*(sq1.top-1);
returnc;
}
voidGetTopOPND(sqstack2&sq1,double&c)
{
if(sq1.top==sq1.base)exit(0);
c=*(sq1.top-1);
}
/*在栈中删除栈顶元素*/
voidPopOPTR(sqstack&sq1,char&c)
{
if(sq1.top==sq1.base)exit(0);
c=*(--sq1.top);
}
voidPopOPND(sqstack2&sq1,double&c)
{
if(sq1.top==sq1.base)exit(0);
c=*(--sq1.top);
}
/*运算函数*/
doubleOperate(doublea,charop,doubleb)
{
switch(op)
{
case'+':
returna+b;break;
case'-':
returnb-a;break;
case'*':
returna*b;break;
case'/':
returnb/a;break;
default:
return0;
}
}
voidmain()
{
sqstackOPTR;
sqstack2OPND;//定义两个栈,一个是数据栈,一个是运算符栈
intm=0;//定义接受字符的个数的变量
printf("输入表达式的长度:
(包含字符的个数,以#结束,例如:
2+3*4#\n");//
scanf("%d",&m);
charch=getchar();//接受输入数据后的回车符
char*p=(char*)malloc(m*sizeof(char));//开辟数组空间
double*q=(double*)malloc(m*sizeof(double));
printf("输入计算的表达式:
");
inti=0,j=0;
do{
scanf("%c",&p[i]);
}while(p[i++]!
='#');
initOPTR(OPTR);
PushOPTR(OPTR,'#');//建立两个栈
initOPND(OPND);
intk=0;q[k]=0;//接收要进入数据栈的整型数据
/*核心的算法*/
charop;doublea,b;
intc=0;
for(j=0;j
{
if((p[j]<='9'&&p[j]>='0')||p[j]=='.')
{
if(p[j]=='.'){c=j;continue;}
else{q[k]=q[k]*10+(double)(p[j]-'0');continue;}
}
else
{
if(q[k])
{
for(intv=0;v=0;v++)
{
q[k]=q[k]/10;
}
PushOPND(OPND,q[k]);//printf("数字栈%d%d",j-1,q[k]);
k++;
q[k]=0;
c=0;
}
switch(precede(GetTopOPTR(OPTR),p[j])){case'<':
PushOPTR(OPTR,p[j]);break;
case'=':
PopOPTR(OPTR,ch);break;
case'>':
PopOPTR(OPTR,op);
PopOPND(OPND,a);
PopOPND(OPND,b);
PushOPND(OPND,Operate(a,op,b));
j--;break;}
}
}
for(j=0;j{
printf("%c",p[j]);
}
printf("=");
GetTopOPND(OPND,a);
printf("%.8f\n",a);
}
五、实验结果及分析
六、实验总结
通过本次编程,学会了要向班上编程好的同学学习啊。
本程序本小组成员经几番讨论最终没能实现,因此只好参考了其他同学的程序,比较不同同学的算法思想觉得以上这个更好,所以参考。
之后我们一定加强自身学习,提高编程能力,减小差距。
七、教师评语和成绩
教师签名:
年月日