数据结构课设表达式求解.docx
- 文档编号:5542091
- 上传时间:2022-12-19
- 格式:DOCX
- 页数:31
- 大小:21.19KB
数据结构课设表达式求解.docx
《数据结构课设表达式求解.docx》由会员分享,可在线阅读,更多相关《数据结构课设表达式求解.docx(31页珍藏版)》请在冰豆网上搜索。
数据结构课设表达式求解
课题名称:
表达式求解
班级:
0008202
学号:
150830114
姓名:
陈鹏
指导教师:
高航
本程序使用栈的数据结构,定义了两个栈OPTR和OPND,分别存储操作符和运算符。
先读取一个以#号结束的表达式,存储在一个字符型数组中。
首先通过判断函数judge判断该表达式的合法性,如果不合法,则重新输入,然后调用函数EvaluateExpression(charn[]),进行运算。
主要的函数EvaluateExpression(charn[])是根据运算符优先法来实行的。
首先判断数组的第一个字符是不是‘#’,如果是,则元素表达式读取完毕,程序也运行结束。
如果不是,则进行一下操作。
判断数组中的元素是运算数还是运算符,运算数通过函数atoi(charn[])取出,进入OPND栈。
然后将后面的部分向前移。
如果是运算符,则将该运算符和OPTR栈栈顶元素的优先级进行比较。
如果该运算符优先级大于OPTR栈顶元素,则运算符进栈。
将后面的部分往前移。
如果该运算符优先级等于OPTR栈顶元素,则栈顶元素出栈,将该运算符后面的部分前移。
如果该运算符优先级小于OPTR栈顶元素,则栈顶元素与OPND栈顶元素与第二个元素出栈,两运算数进行与栈顶元素相对应的运算,再将运算结果进OPND栈。
如果该运算符优先级仍低于OPTR栈栈顶元素或两者优先级相等,则重复上述过程,直至该运算符优先级高于栈顶元素。
程序设计的另一个要求是输出栈的变化过程。
本程序直接采用cout输出栈的变化,每次OPTR栈有变化的时候,都依次输出表达式、OPND、OPTR,知道最后表达式输入完毕,栈的输出也完毕,最后读出OPND栈中最后的元素,即为运算结果。
实现的源程序:
//****************************************************************************
//程序名称:
表达式求解
//程序要求:
1.从键盘读入一个合法的算术表达式,输出正确的结果。
//2.显示输入序列和栈的变化过程。
//程序作者:
陈鹏
//班级:
0008202
//学号:
150830114
//完成日期:
2009.12.25
//****************************************************************************
#include
usingnamespacestd;
//定义一个存放字符类型的结构体
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
typedefstruct
{
char*base;
char*top;
intstacksize;
}SqStack;
//定义一个存放整数类型的结构体
typedefstruct
{
int*base;
int*top;
intstacksize;
}SqStack1;
//*****************************************************************************
//
//栈的基本操作函数
//
//*****************************************************************************
//初始化一个字符型栈
voidInitStack(SqStack&S)
{
S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
if(!
S.base)
exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
//初始化一个整型的栈
voidInitStack1(SqStack1&S)
{
S.base=(int*)malloc(STACK_INIT_SIZE*sizeof(int));
if(!
S.base)
exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
//销毁字符型栈
voidDestroyStack(SqStack&S)
{
free(S.base);
}
//销毁整型的栈
voidDestroyStack1(SqStack1&S)
{
free(S.base);
}
//清空栈
voidClearStack(SqStack&S)
{
S.top=S.base;
}
//判空
boolStackEmpty(SqStack&S)
{
if(S.base==S.top)
returntrue;
else
returnfalse;
}
//返回栈中元素个数
intStackLength(SqStackS)
{
returnS.top-S.base;
}
//返回字符型栈顶元素
charGetTop(SqStackS,char&e)
{
if(S.top==S.base)
{
cout<<"栈为空栈!
";
return0;
}
else
{
e=*(S.top-1);
returne;
}
}
//返回整型栈顶元素
intGetTop1(SqStack1S,int&e)
{
if(S.top==S.base)
{
cout<<"栈为空栈!
";
return0;
}
else
{
e=*(S.top-1);
returne;
}
}
//字符型进栈操作
voidPush(SqStack&S,chare)
{
//栈满,追加存储空间
if(S.top-S.base>=S.stacksize)
{
S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
if(!
S.base)
exit(0);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top=e;
S.top++;
}
//整形进栈操作
voidPush1(SqStack1&S,int&e)
{
//栈满,追加存储空间
if(S.top-S.base>=S.stacksize)
{
S.base=(int*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));
if(!
S.base)
exit(0);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top=e;
S.top++;
}
//字符型栈顶元素出栈
voidPop(SqStack&S,char&e)
{
if(S.base==S.top)
cout<<"栈为空栈!
";
e=*(S.top-1);
S.top=S.top-1;
}
//整型栈顶元素出栈
voidPop1(SqStack1&S,int&e)
{
if(S.base==S.top)
cout<<"栈为空栈!
";
e=*(S.top-1);
S.top=S.top-1;
}
//从栈底到栈顶对栈中每个元素调用函数visit()
voidStackTraverse(SqStackS,char(*visit)(charm))
{
if(S.base==S.top)
{
cout<<"栈为空栈";
}
else
{
for(inti=0;S.base+i { visit(*(S.base+i)); } } } voidStackTraverse1(SqStack1S,int(*visit)(intm)) { if(S.base==S.top) { cout<<"栈为空栈"; } else { for(inti=0;S.base+i { visit(*(S.base+i)); } } } //***************************************************************************** // //判断表达式合法性函数 // //***************************************************************************** //判断表达式的合法性 //判断第一个字符 //不能为‘+’‘-’‘*’‘/’‘)’‘#’ booljudge1(charn[]) { if(n[0]=='+'||n[0]=='-'||n[0]=='*'||n[0]=='/'||n[0]==')'||n[0]=='#') returnfalse; else returntrue; } //判断‘(’和‘)’的个数是否相等 //不相等则非法 booljudge2(charn[]) { inta; intb; a=0; b=0; for(inti=0;n[i]! ='#';i++) { if(n[i]=='(') { a++; } if(n[i]==')') { b++; } } if(a==b) { returntrue; } else returnfalse; } //判断‘/’号之后是否为0 //如果是0则非法 booljudge3(charn[]) { for(inti=0;n[i]! ='#';i++) { if(n[i]=='/') { if(n[i+1]=='0') { returnfalse; } } } returntrue; } //判断是否存在两个运算符连在一起的情况 //若存在则非法 booljudge4(charn[]) { for(inti=0;n[i]! ='#';i++) { if(n[i]=='+'||n[i]=='-'||n[i]=='*'||n[i]=='/') { if(n[i+1]=='+'||n[i+1]=='-'||n[i+1]=='*'||n[i+1]=='/') returnfalse; } } returntrue; } //判断其中是否含有除了操作数和运算符之外的符号 //若存在,则非法 booljudge5(charn[]) { for(inti=0;n[i]! ='#';i++) { if(n[i]! ='+'&&n[i]! ='-'&&n[i]! ='*'&&n[i]! ='/' &&n[i]! ='('&&n[i]! =')'&&n[i]! ='#'&&n[i]! ='0' &&n[i]! ='1'&&n[i]! ='2' &&n[i]! ='3'&&n[i]! ='4'&&n[i]! ='5'&& n[i]! ='6'&&n[i]! ='7'&&n[i]! ='8'&& n[i]! ='9') { returnfalse; } } returntrue; } //judge函数 //将以上几种情况一起考虑 //返回true为合法 //返回false为非法 booljudge(charn[]) { if(! judge1(n)) { returnfalse; } if(! judge2(n)) { returnfalse; } if(! judge3(n)) { returnfalse; } if(! judge4(n)) { returnfalse; } if(! judge5(n)) { returnfalse; } returntrue; } //***************************************************************************** // //实现的其他函数 // //***************************************************************************** //判断是否为运算数 booldigit(chara) { if(a=='1'||a=='2'||a=='3'||a=='4'||a=='5'||a=='6'||a=='7'||a=='8'||a=='9'||a=='0') returntrue; else returnfalse; } //判断整数的位数 //不断除以10 //知道结果为0,记录除的次数 intsize(inta) { inti; i=1; while(a/10! =0) { i=i+1; a=a/10; } returni; } //判断运算符优先级函数 //先将'+''-''*''/''('')''#'存在两个一维数组中 //将对照表存在二维数组中 //先找出与进行比较的运算符对应的数组坐标 //再在二维数组中找出与之对应的关系 charPrecede(chara,charb) { intp,q; charx[7]; x[0]='+'; x[1]='-'; x[2]='*'; x[3]='/'; x[4]='('; x[5]=')'; x[6]='#'; chary[7]; y[0]='+'; y[1]='-'; y[2]='*'; y[3]='/'; y[4]='('; y[5]=')'; y[6]='#'; charcheck[7][7]= { {'>','>','<','<','<','>','>'}, {'>','>','<','<','<','>','>'}, {'>','>','>','>','<','>','>'}, {'>','>','>','>','<','>','>'}, {'<','<','<','<','<','=',''}, {'>','>','>','>','','>','>'}, {'<','<','<','<','<','','='} }; for(inti=0;i<=6;i++) { if(x[i]==a) { p=i; break; } } for(intj=0;j<=6;j++) { if(y[j]==b) { q=j; break; } } returncheck[p][q]; } //Opetate函数 //判断theta为何种运算符 //在进行相应的操作 intOperate(inta,chartheta,intb) { if(theta=='+') returna+b; else if(theta=='-') returna-b; else if(theta=='*') returna*b; else returna/b; } //输出栈OPTR中的元素 voidprint(SqStackn) { if(n.base=='\0') { cout<<'\0'; } else { for(inti=0;i { cout<<*(n.base+i); cout<<''; } } } //输出栈OPND中的元素 voidprint1(SqStack1n) { for(inti=0;i { cout<<*(n.base+i); cout<<''; } } //输出表达式 voidprint2(charn[]) { if(n[0]=='#') { cout<<"表达式输入完毕"; } else { for(inti=1;n[i]! ='\0';i++) { cout< } } } //输出表达式 voidprint3(charn[]) { if(n[0]=='\0') { cout<<"表达式输入完毕"; } else { for(inti=0;n[i]! ='\0';i++) { cout< } } } //***************************************************************************** // //算符优先法 // //***************************************************************************** voidEvaluateExpression(charn[]) { //定义一个运算符栈和一个运算数栈 SqStackOPTR; SqStack1OPND; InitStack(OPTR); //‘#’先进栈 Push(OPTR,'#'); InitStack1(OPND); //第一次输出 cout<<"表达式: "; print3(n); cout< cout<<"OPTR栈: "; print(OPTR); cout< cout<<"OPND栈为空栈"; cout< cout< chare; charf; intg=0; charx; chartheta; inta; intb; while(n[0]! ='\0'||GetTop(OPTR,e)! ='\0') { //运算符进栈 if(digit(n[0])) { //如果n[k]是运算数,d为取出这个运算数 intd=0; d=atoi(n); Push1(OPND,d); intsi=0; //si为取出运算数的位数 si=size(d); //将数组从数字位后面的依次前移 for(inth=si;n[h]! ='#';h++) { n[h-si]=n[h]; } n[h-si]=n[h]; //将‘#’后一位置'\0' n[h-si+1]='\0'; cout<<"表达式: "; print3(n); cout< cout<<"OPTR栈: "; print(OPTR); cout< cout<<"OPND栈: "; print1(OPND); cout< cout< } else switch(Precede(GetTop(OPTR,f),n[0])) { case'<': //运算符进栈 { Push(OPTR,n[0]); //将运算符后的部分依次前移 for(intl=1;n[l]! ='#';l++) { n[l-1]=n[l]; } n[l-1]=n[l]; n[l]='\0'; cout<<"表达式: "; print3(n); cout< cout<<"OPTR栈: "; print(OPTR); cout< cout<<"OPND栈: "; print1(OPND); cout< cout< break; } case'=': //脱括号并接受下一个字符 { //结束 if(n[0]=='#') { cout<<"表达式: "; cout<<"表达式输入完毕"; cout< Push(OPTR,'#'); cout<<"OPTR栈: "; print(OPTR); cout< cout<<"OPND栈: "; print1(OPND); cout< cout< //将两个'#'出栈 Pop(OPTR,x); Pop(OPTR,x); Push(OPTR,'\0'); n[0]='\0'; cout<<"表达式: "; cout<<"表达式输入完毕"; cout< cout<<"OPTR栈: "; print(OPTR); cout< cout<<"OPND栈: "; print1(OPND); cout< } else { Push(OPTR,n[0]); //将运算符后的部分依次前移 for(intl=1;n[l]! ='#';l++) { n[l-1]=n[l]; } n[l-1]=n[l]; n[l]='\0'; cout<<"表达式: "; print3(n); cout< cout<<"O
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 表达式 求解