数据结构课程设计.docx
《数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计.docx(38页珍藏版)》请在冰豆网上搜索。
![数据结构课程设计.docx](https://file1.bdocx.com/fileroot1/2023-1/8/c9853194-5616-4e4d-b8fc-52dd38a02cc7/c9853194-5616-4e4d-b8fc-52dd38a02cc71.gif)
数据结构课程设计
24点游戏
一、课程设计的目的和要求
本课程设计是为了配合《数据结构》课程的开设,通过设计一完整的程序,使学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并用TC上机调试的基本方法。
使学生了解并掌握数据结构与算法的设计方法,并且
具备初步的独立分析和设计能力。
通过这个课程的学习,让学生们初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能,还可以提高综合运用所学的理论知识和方法独立分析和解决问题的能力。
课程设计的要求即为:
1、要充分认识课程设计对自己的重要性,认真做出设计前的各项准备工作。
2、既要虚心接受老师的指导,又要充分发挥主观能动性相结合课题,独立思考,努力钻研,勤于实践,勇于创新。
3、独立按时完成规定的工作任务,不得弄虚作假,不准抄袭他人内容。
则成绩以不及格计。
4、在设计过程中,要严格要求自己,树立严肃、严密、严谨的科学态度,必须按时、按质、按量完成课程设计。
二、设计的主要内容
24点游戏是一种简单的益智类游戏游戏内容为:
从1—13中,任意抽取4个数字,运用加、减、乘、除和括号等运算符把这些数字进行一系列的运算,运算得到的结果应为24。
并且每个数都必须参与运算,每个数字只能运算一次,运算符可多次重复使用。
当用户正确输入算式后,程序根据“堆栈来求表达式的值”的原理,求出结果并判断是否为24,得出用户是输是赢的结论。
输出结果后,询问用户是否继续,是则重新启动程序,否则结束程序。
三、概要设计
1.模块分析
24算法游戏的功能模块不多,也比较容易实现。
基本思想就是由程序先随机产生4张扑克牌,每张扑克牌对应一个整数,所以首先要有一个随机产生扑克牌的模块。
接下来就是用户用程序产生的扑克牌来算24点了,所以要有一个输入用户去接表达式的模块。
用户输入完成后,判断输入表达式是否合法,所以要有一个判断表达式合法与否的模块。
如果表达式合法程序就开始计算表达式了,所以要有一个计算表达式的模块。
程序计算完表达式后就要判断用户输入的表达式是不是为24点了,所以还有一个判断表达式正误的模块。
这5个模块是逐步
递进的,是要前一个模块的功能完成后,才能执行后一个模块,否则程序就将出错。
程序所涉及的数据结构主要为整形和字符型,整形数据结构主要是用来计算表达式的,字符型数据结构主要是用来输入表达式的。
程序所涉及的数据库结构主要有数组和栈,数组在计算表达式和产生扑克牌是都要用到,栈只是用来计算表达式的。
判断表达式是否合法。
2.功能模块图
图1.功能模块图
四、运行环境
硬件环境:
PC机
软件环境:
WindowsXPMicrosoftVisualC++6.0
五、详细设计
1.运行程序:
enum
{
eNumber=0,//操作数
eOperator=1//算子
};
intoper[7]={43,45,42,47,40,41,35};
typedefstructsqlist{
intbol;//bolis0whennum_chisanumber;bolis1whenthenum_chisaoprater
intnum_ch;
structsqlist*next;
}sqlist;
typedefstructsqstack{
int*base;#include
#include
#include
#include
#defineMAX13
#defineOK1
#defineTRUE1
#defineFALSE0
#defineERROR0
#defineOVERFLOW-2
#defineOPSETSIZE7
#defineSTACK_INIF_SIZE50
#defineSTACKINCREMENT10
typedefintstatus;
intnumber[2][4];
int*top;
intstacksize;
}sqstack;
unsignedcharPrior[7][7]={//表3.1算符间的优先关系
'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=','',
'>','>','>','>','','>','>',
'<','<','<','<','<','','='
};
charOPSET[OPSETSIZE]={'+','-','*','/','(',')','#'};
statusinit_sq(sqlist*l){//初始化链表
l=(sqlist*)malloc(sizeof(sqlist));
if(l==NULL){
exit(OVERFLOW);
}
l->next=NULL;
returnOK;
}
statusinsert_sq(sqlist**p,inte,intbl){//链表插入操作
sqlist*q;
q=(sqlist*)malloc(sizeof(sqlist));
q->num_ch=e;
q->bol=bl;
q->next=NULL;
(*p)->next=q;
(*p)=(*p)->next;
//printf("insert%d,%dissuccssed!
\n",e,bl);
returnOK;
}
intcheck(sqlistl)//保证输入的数字是给出的四个数字
{
intright=1,find=0,i;
sqlist*q=&l;
q=q->next;
for(;q->next!
=NULL;q=q->next)
{
if(q->bol==1){
if(q->num_ch
<=39||q->num_ch>57||q->num_ch==44||q->num_ch==46){
right=0;
printf("%c不是有效的运算符!
\n");
}
}
else{
find=0;
for(i=0;i<4;i++){
if(number[1][i]==0&&number[0][i]==q->num_ch){
number[1][i]=1;
find=1;
break;
}
}
if(find==0){
printf("%d不在给出的四个数字中!
\n",q->num_ch);
right=0;
}
}
}//endfor
for(i=0;i<4;i++){
if(number[1][i]==0){
printf("%d没有用上!
\n",number[0][i]);
right=0;
}
}
returnright;
}
intchang(char*s,sqlist*l){//将用户的输入转化为单链表
intt=0;
unsignedinti=0;
intbl,ch;
inta1,a2,a;
sqlist*p=l;
for(;iif(s[i]>47&&s[i]<58&&t==0){
a1=(int)s[i]-48;
t++;
}
elseif(s[i]>47&&s[i]<58&&t==1){
a2=(int)s[i]-48;
a=a1*10+a2;
t++;
}
elseif(s[i]<48&&s[i]>39&&s[i]!
=44&&s[i]!
=46){
if(t==1){
bl=0;
insert_sq(&p,a1,bl);
t=0;
}
elseif(t==2){
bl=0;
insert_sq(&p,a,bl);
t=0;
}
bl=1;
ch=(int)s[i];
insert_sq(&p,ch,bl);
t=0;
}
else{
printf("%c不是有效的运算符!
\n",s[i]);
}
}//endfor
i=strlen(s)-1;
if(s[i]>47&&s[i]<58){
if(s[i-1]>47&&s[i-1]<58){
bl=0;
insert_sq(&p,a,bl);
}
else{
bl=0;
insert_sq(&p,a1,bl);
}
}
bl=1;
a=35;
insert_sq(&p,a,bl);
//printf("changisOK\n");
return(check(*l));
}
intOperate(inta,inttheta,intb){//计算
//printf("a=%d,theta=%c,b=%d\n",a,theta,b);
switch(theta){
case43:
returna+b;
case45:
returna-b;
case42:
returna*b;
case47:
{
if(b==0){
return-2000;
}
if(a%b==0){
returna/b;
}
else{//printf("不能为小数\n");
return-10000;
}
}
default:
return0;
}
}
intReturnOpOrd(charop,char*TestOp){//被charprecede(charAop,charBop)所调用来求优先级
inti;
for(i=0;iif(op==TestOp[i])returni;
}
return0;
}
charprecede(charAop,charBop){
returnPrior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}
statusinitstack(sqstack*s){
(s)->base=(int*)malloc(STACK_INIF_SIZE*sizeof(int));
if((s)->base==NULL)exit(OVERFLOW);
(s)->top=(s)->base;
(s)->stacksize=STACK_INIF_SIZE;
//printf("栈初始化完成!
\n");
returnOK;
}
intgettop(sqstack*s){
inte;
if(s->top==s->base){
printf("栈空,无法取得栈顶元素!
\n");
return0;
}
e=*(s->top-1);
//printf("取得栈顶元素:
%d\n",e);
returne;
}
statuspush(sqstack*s,inte){
if(s->top-s->base>=s->stacksize){
s->base=(int*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(int));
if(!
s->base)exit(OVERFLOW);
s->stacksize+=STACKINCREMENT;
}
*(s->top++)=e;
//printf("把%d压栈isOK\n",e);
returnOK;
}
statuspop(sqstack*s,int*e){
if(s->top==s->base){
printf("栈空,出栈错误!
\n");
returnERROR;
}
*e=*(--s->top);
//printf("%d出栈成功!
\n",*e);
returnOK;
}
intEvaluateExpression(char*MyExpression){//算法3.4
//算术表达式求值的算符优先算法。
//设OPTR和&&OPND分别为运算符栈和运算数栈,OP为运算符集合。
intresult;
sqstackOPTR;//运算符栈,字符元素
sqstackOPND;//运算数栈,实数元素
intc,bl,a,b,theta,top;
sqlist*q,l;
char*s=MyExpression;
init_sq(&l);
if(chang(s,&l)!
=0){
q=&l;
initstack(&OPTR);
push(&OPTR,35);
initstack(&OPND);
q=q->next;
c=q->num_ch;
bl=q->bol;
while((c!
=35||gettop(&OPTR)!
=35)){
if(bl!
=1){
push(&OPND,c);
q=q->next;
c=q->num_ch;
bl=q->bol;
}//不是运算符则进栈
else{
top=gettop(&OPTR);
//printf("top%c",top);
switch(precede(top,c)){
case'<':
//栈顶元素优先权低
push(&OPTR,c);
q=q->next;
c=q->num_ch;
bl=q->bol;
break;
case'=':
//脱括号并接收下一字符
pop(&OPTR,&c);
q=q->next;
c=q->num_ch;
bl=q->bol;
break;
case'>':
//退栈并将运算结果入栈
pop(&OPTR,&theta);
pop(&OPND,&b);
pop(&OPND,&a);
//printf("q->num_chis%d\n",q->num_ch);
push(&OPND,Operate(a,theta,b));
break;
default:
printf("没有这个运算符!
\n");
return0;
}//switch
}//else
}//while
result=gettop(&OPND);
returnresult;
}
else{
printf("你的输入有错误!
\n");
return0;
}
}//EvaluateExpression
intrandomm()//产生四个随机数
{
inti=0;
srand((unsigned)time(NULL));
for(;i<4;i++){
number[0][i]=0;
number[0][i]=rand();
number[0][i]%=13;
number[0][i]++;
number[1][i]=0;
}
returnnumber[2][4];
}
intCalcOneExpress(intexpression[][2])
{
//算术表达式求值的算符优先算法。
//设OPTR和&&OPND分别为运算符栈和运算数栈,OP为运算符集合。
intindex=0,result,c,theta,a,b;
sqstackOPTR;//运算符栈,字符元素
sqstackOPND;//运算数栈,实数元素
initstack(&OPTR);
push(&OPTR,35);
initstack(&OPND);
c=expression[index][0];
while(c!
=35||gettop(&OPTR)!
=35){
if(expression[index][1]!
=1){
push(&OPND,c);
index++;
c=expression[index][0];
}//不是运算符则进栈
else{
switch(precede(gettop(&OPTR),c)){
case'<':
//栈顶元素优先权低
push(&OPTR,c);
index++;
c=expression[index][0];
break;
case'=':
//脱括号并接收下一字符
pop(&OPTR,&c);
index++;
c=expression[index][0];
break;
case'>':
//退栈并将运算结果入栈
pop(&OPTR,&theta);
pop(&OPND,&b);
pop(&OPND,&a);
push(&OPND,Operate(a,theta,b));
break;
default:
printf("没有这个运算符\n");
return0;
}//switch
}//else
}//while
result=gettop(&OPND);
returnresult;
}//EvaluateExpression
intEqual24(intn)
{
if(n==24){
//printf("theresultis%d\n",n);
returnTRUE;
}
elsereturnFALSE;
}
//括号的几种情况
//1无括号
//2(ab)cd同ab(cd),下省略
//3(abc)d
//4a(bc)d
//5(ab)(cd)
//6((ab)c)d
//7(a(bc))d
intCalcArray1(intiNumInput[2][4])
{
//a*b*c*d//7number
intexpression[8][2],ii,jj,kk;
inti,j,k,l,dRes;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(j==i)
{
continue;
}
for(k=0;k<4;k++)
{
if(k==i||k==j)
{
continue;
}
for(l=0;l<4;l++)
{
if(l==i||l==j||l==k)
{
continue;
}
expression[0][0]=iNumInput[0][i];
expression[2][0]=iNumInput[0][j];
expression[4][0]=iNumInput[0][k];
expression[6][0]=iNumInput[0][l];
expression[0][1]=eNumber;
expression[2][1]=eNumber;
expression[4][1]=eNumber;
expression[6][1]=eNumber;
for(ii=0;ii<4;ii++)
{
for(jj=0;jj<4;jj++)
{
for(kk=0;kk<4;kk++)
{
expression[1][0]=oper[ii];
expression[1][1]=eOperator;
expression[3][0]=oper[jj];
expression[3][1]=eOperator;
expression[5][0]=oper[kk];
expression[5][1]=eOperator;
expression[7][0]=oper[6];
expression[7][1]=eOperator;
dRes=CalcOneExpress(expression);
if(Equal24(dRes))
{
printf("可以这样运算:
%d%c%d%c%d%c%d\n",expression[0][0],oper[ii],expression[2][0],oper[jj],expression[4][0],oper[kk],expression[6][0]);
returnTRUE;
}
}
}
}//endofforoper
}
}
}
}
returnFALSE;
}
intCalcArray2(intiNumInput[2][4])
{
//(a*b)*c*d//9number
intexpression[10][2];
intii,jj,i,j,k,l,kk;
intdRes;
//printf("CalcArray2\n");
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(j==i)
{
continue;
}
for(k=0;k<4;k++)
{
if(k==i||k==j)
{
continue;
}
for(l=0;l<4;l++)
{
if(l==i||l==j||l==k)
{
continue;
}
expression[1][0]=iNumInput[0][i];
expression[3][0]=iNumInput[0][j];
expression[6][0]=iNu