课程设计课程设计名称:数据结构课程设计专业班级:学生姓名:学号:指导教师:课程设计时间:1计算机科学与技术专业课程设计任务书学生姓名专业班级学号题目24点游戏课题性质其它课题来源自拟课题指导教师同组姓名主要内容一副牌共54张,除去大小King,还剩52张,从中任意取四张加入括号和加减乘除运算符,组成表达式,并使表达式的值等于24。(注:1.每张牌只能用一次;2.有些数字组合不能是表达式的值为24)任务要求1.程序产生四个随机的数字(在1-13之间),由用户计算24点2.用户输入四个数字(在1-13之间),由程序计算24点参考文献1张凤琴,张青凤.数据结构学习指导与习题详解,清华大学出版社,20072严蔚敏,吴伟民.数据结构(C语言版).清华大学出版社,20083潭浩强.C语言程序设计(第三版).清华大学出版社,20054潭浩强.C语言程序设计题解与上机指导(第三版).清华大学出版社,20055张曼,朱小谷,吕士俊.数据结构习题与解答.北京希望电子出版社.2005审查意见指导教师签字:教研室主任签字:年月日21.需求分析24点游戏主要有两个功能:(1)用户记算24点程序随机产生四个1-13的数,分别代表4张牌,提示用户输入算式。如果用户认为程序给出的一组数字不能算出24点(如1,1,2,2),则输入‘?’,然后程序对四个数字进行计算,如果真的不能算出24点,则输出用户正确的信息,否则给出一个正确的算式,并显示用户错误的信息。(2).程序计算24点用户输入四个1-13的数,代表4张牌,程序需要通过一定的规则添加括号和运算符来使算式的值等于24,如果用户给出的四个数字不能算出24点,则输出错误信息!2.概要设计○1抽象数据结构定义:ADT{数据对象:D={a|a为大于0小于14的整数}push(sqstack*s,inte)//压栈gettop(sqstack*s)//取得栈顶元素pop(sqstack*s,int*e)//出栈randomm()//产生四个随机数EvaluateExpression(char*MyExpression)//课本算法3.4---计算表达式的值init_sq(sqlist*l)//初始化链表insert_sq(sqlist**p,inte,intbl)//链表插入操作chang(char*s,sqlist*l)//将用户的输入转化为单链表check(sqlistl)//保证输入的数字是给出的四个数字Operate(inta,inttheta,intb)//计算precede(charAop,charBop)//求运算符优先级ReturnOpOrd(charop,char*TestOp)//返回运算符优先级3CalcOneExpress(intexpression[][2])//课本算法3.4--计算表达式的值Calc24(intnumber[2][4])//包含下面五个函数,即表达式的五种形式CalcArray1(intiNumInput[2][4])//a*b*c*d//7个字符CalcArray2(intiNumInput[2][4])//(a*b)*c*d//9numberCalcArray3(intiNumInput[2][4])//(a*b*c)*d//9numberCalcArray4(intiNumInput[2][4])//(a*b)*(c*d)//11numbersCalcArray5(intiNumInput[2][4])//((a*b)*c)*d//11numbersEqual24(intn)//判定结果是否等于24gameinformation()//游戏介绍menu()//菜单main()//主函数}ADT○2模块划分4Main()游戏介绍人算24点程序算24点计算24点并输出算式用户输入算式用户认为无法算出24点程序验证,输出正确或错误信息,用户继续玩程序验证,若能算出24点,则输出正确算式无法算出24点,输出错误信息3运行环境硬件环境:PC机软件环境:WindowsXPMicrosoftVisualC++6.04开发工具和编程语言开发工具:MicrosoftVisualC++6.0编程语言:C语言5详细设计(1)全局变量和栈,链表的定义intnumber[2][4];enum{eNumber=0,//操作数eOperator=1//算子};5intoper[7]={43,45,42,47,40,41,35};课本表3.1算符间的优先关系:unsignedcharPrior[7][7]={'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','=','','','','','','','','','','','','','','','='};线性表的定义:typedefstructsqlist{intbol;//bol是0时,num-ch是数字;bol是1时num_ch是运算符intnum_ch;structsqlist*next;}sqlist;栈的定义:typedefstructsqstack{int*base;int*top;intstacksize;}sqstack;6(2)main()函数及用户界面voidmain(){gameinformation();//输出作者信息menu();//输出功能菜单,游戏开始}用户界面如图1所示。(3)由程序计算24点的算法分析:用户输入四个1-13的数,代表4张牌,程序算24点。这要考虑到各种情况。首先是加入括号,有以下5种可能的形式:□1.abcd□2.(ab)cd同ab(cd)和a(bc)d□3.(abc)d□4.(ab)(cd)□5.((ab)c)d同(a(bc))d然后根据上述5种情况加入运算符。对于每种不同的算式形式,先在固定的位置加入括号。程序通过4层循环对四个数字进行赋值,并对循环加以控制,使每个数字只用一次,然后再通过三层循环对三个位置的运算符赋值。每一次循环都会产生一个数组,别调用下面的CalcOneExpress函数求算式的值!结果可能算出24点,或者算不出24点(如图2,图3)。以下两段代码是对针对第一种形式的算式求24点。过程为:对四个数字和三个运算符赋值(CalcArray1(intiNumInput[2][4]))----计算算式的值(CalcOneExpress(intexpression[][2]))---验证是否等于24---输出结果:代码1.//a*b*c*d7个字符7intCalcArray1(intiNumInput[2][4]){intexpression[8][2],ii,jj,kk;inti,j,k,l,dRes;for(i=0;i4;i++){for(j=0;j4;j++){if(j==i)continue;for(k=0;k4;k++){if(k==i||k==j)continue;for(l=0;l4;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;ii4;ii++){for(jj=0;jj4;jj++){for(kk=0;kk4;kk++)8{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);//对每一个算式求值,直到算出24点if(Equal24(dRes))//判定表达式的值是否为24{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]);return1;}}}}}}}return0;}9代码2.//课本算法3.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((char)gettop(&OPTR),(char)c)){case''://栈顶元素优先权低push(&OPTR,c);index++;c=expression[index][0];10break;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}//whileresult=gettop(&OPND);returnresult;}//endCalcOneExpress(4)由用户计算24点的算法分析:○1先由程序产生4个随机数;intrandomm(){inti=0;srand((unsigned)time(NULL));for(;i4;i++){11number[0][i]=0;number[0][i]=rand();number[0][i]%=13;number[0][i]++;number[1][i]=0;}returnnumber[2][4];}○2用户判定如果用户认为程序产生的四个随机数不能算出24点则输入‘?’,程序接收到该字符后,则进行步骤(3)的操作,如果真的不能算出24点,则输出用户正确的信息,否者输出用户错误的信息,并输出一个正确的算式。(请看图4,图5,图6)如果用户认为可以算出24点,则输入算式,程序对此算式求值,若结果为24,程序输出用户正确的信息,否则输出用户错误的信息。此过程中,程序先将用户输入的算式转化成单链表的形式,其功能和步骤(2)中的数组是基本一样的。然后检验用户输入的算式中是否有非法字符,若有这输