![數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料_第1頁](http://file4.renrendoc.com/view/76754fb47f5fdfa2561598f2aad95691/76754fb47f5fdfa2561598f2aad956911.gif)
![數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料_第2頁](http://file4.renrendoc.com/view/76754fb47f5fdfa2561598f2aad95691/76754fb47f5fdfa2561598f2aad956912.gif)
![數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料_第3頁](http://file4.renrendoc.com/view/76754fb47f5fdfa2561598f2aad95691/76754fb47f5fdfa2561598f2aad956913.gif)
![數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料_第4頁](http://file4.renrendoc.com/view/76754fb47f5fdfa2561598f2aad95691/76754fb47f5fdfa2561598f2aad956914.gif)
![數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料_第5頁](http://file4.renrendoc.com/view/76754fb47f5fdfa2561598f2aad95691/76754fb47f5fdfa2561598f2aad956915.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料(可以直接使用,可編輯優(yōu)秀版資料,歡迎下載)
數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)報(bào)告匯編(完整版)資料(可以直接使用,可編輯優(yōu)秀版資料,歡迎下載)一、需求分析【課程設(shè)計(jì)要求】【問題的描述】一個表達(dá)式和一棵二叉樹之間,存在著自然的對應(yīng)關(guān)系。寫一個程序,實(shí)現(xiàn)基于二叉樹表示的算術(shù)表達(dá)式Expression的操作?!净疽蟆俊疽弧俊颈刈霾糠帧考僭O(shè)算術(shù)表達(dá)式Expression內(nèi)可以含有變量(a-z),常量(0-9)和二元運(yùn)算符(+,-,*,/,^(乘冪))。實(shí)現(xiàn)以下操作:(1)ReadExpr(E)――以字符序列的形式輸入語法正確的前綴表達(dá)式并構(gòu)造表達(dá)式E。(2)WriteExpr(E)――用帶括號的中綴表達(dá)式輸出表達(dá)式E。(3)Assign(V,c)――實(shí)現(xiàn)對變量V的賦值(V=c),變量的初值為0。(4)Value(E)――對算術(shù)表達(dá)式E求值。(5)CompoundExpr(p,E1,E2)――構(gòu)造一個新的復(fù)合表達(dá)式(E1)p(E2)。【二】【選做部分】(1)以表達(dá)式的原書寫形式輸入,支持大于0的正整數(shù)常量;(2)增加常數(shù)合并操作MergeConst(E)——合并表達(dá)式E中所有常數(shù)運(yùn)算。例如,對表達(dá)式E=(2+3-a)*(b+3*4)進(jìn)行合并常數(shù)的操作后,求得E=(5-a)*(b+12)(3)增加對求偏導(dǎo)數(shù)的運(yùn)算Diff(E,V)——求表達(dá)式E對V的導(dǎo)數(shù)(4)在表達(dá)式內(nèi)增加對三角函數(shù)等初等函數(shù)的操作?!緶y試數(shù)據(jù)】(1)分別輸入0;a;-91;+a*bc;+*5x2*8x;+++*3^*2^x2x6并輸出。(2)每當(dāng)輸入一個表達(dá)式后,對其中的變量賦值,然后對表達(dá)式求值二、【整體算法思想】一個表達(dá)式和一棵二叉樹之間存在一一對應(yīng)的關(guān)系。本程序我主要用前綴表達(dá)式建樹,中序遍歷并適當(dāng)加括號實(shí)現(xiàn)中綴輸出。具體操作即對樹的程序進(jìn)行處理,再輸出。三、【概要設(shè)計(jì)】1、數(shù)據(jù)類型的聲明: 在這個課程設(shè)計(jì)中,采用了鏈表二叉樹的存儲結(jié)構(gòu),以及兩個順序棧的輔助存儲結(jié)構(gòu)/*頭文件以及存儲結(jié)構(gòu)*/ #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<string.h> #defineTRUE1 #defineFALSE0 #defineOK1 #defineERROR0 #defineOVERFLOW0 typedefintStatus; 2、表達(dá)式的抽象數(shù)據(jù)類型定義ADTExpression{數(shù)據(jù)對象D:D是具有數(shù)值的常量C和沒有數(shù)值的變量V;數(shù)據(jù)關(guān)系:R={<(V或者C)P(V或者C)>|V,C∈D,<(V或者C)P(V或者C)>表示由運(yùn)算符P結(jié)合起來的表達(dá)式E}基本操作:StatusInput_Expr(&string,flag)操作結(jié)果:以字符序列的形式輸入語法正確的前綴表達(dá)式,保存到字符串string;參數(shù)flag表示輸出的提示信息是什么,輸入成功返回OK,否則,返回ERROR。voidjudge_value(&E,&string,i)初始條件:樹E存在,表達(dá)式的前綴字符串string存在;操作結(jié)果:判斷字符string[i],如果是'0'-'9'常量之間,二叉樹結(jié)點(diǎn)E存為整型;否則,存為字符型。StatusReadExpr(&E,&exprstring)初始條件:表達(dá)式的前綴形式字符串exprstring存在;操作結(jié)果:以正確的前綴表示式exprstring并構(gòu)造表達(dá)式E,構(gòu)造成功,返回OK,否則返回ERROR。StatusPri_Compare(c1,c2)初始條件:c1和c2是字符;操作結(jié)果:如果兩個字符是運(yùn)算符,比較兩個運(yùn)算符的優(yōu)先級,c1比c2優(yōu)先,返回OK,否則返回ERROR。voidWriteExpr(&E)初始條件:表達(dá)式E存在;操作條件:用帶括弧的中綴表達(dá)式輸入表達(dá)式E。voidAssign(&E,V,c,&flag)初始條件:表達(dá)式E存在,flag為標(biāo)志是否有賦值過;操作結(jié)果:實(shí)現(xiàn)對表達(dá)式E中的所有變量V的賦值(V=c)。longOperate(opr1,opr,opr2)初始條件:操作數(shù)opr1和操作數(shù)opr2以及操作運(yùn)算符opr;操作結(jié)果:運(yùn)算符運(yùn)算求值,參數(shù)opr1,opr2為常量,opr為運(yùn)算符,根據(jù)不同的運(yùn)算符,實(shí)現(xiàn)不同的運(yùn)算,返回運(yùn)算結(jié)果。StatusCheck(E)初始條件:表達(dá)式E存在;操作結(jié)果:檢查表達(dá)式E是否還存在沒有賦值的變量,以便求算數(shù)表達(dá)式E的值。longValue(E)初始條件:表達(dá)式E存在;操作結(jié)果:對算術(shù)表達(dá)式求值,返回求到的結(jié)果。voidCompoundExpr(P,&E1,E2)初始條件:表達(dá)式E1和E2存在;操作條件:構(gòu)造一個新的復(fù)合表達(dá)式(E1)P(E2)。StatusRead_Inorder_Expr(&string,&pre_expr)操作結(jié)果:以表達(dá)式的原書寫形式輸入,表達(dá)式的原書寫形式字符串string變?yōu)樽址畃re_expr,后調(diào)用reversal_string()函數(shù)反轉(zhuǎn)得到前綴表達(dá)式pre_expr。得到正確的前綴表達(dá)式返回OK,否則,返回ERROR。voidMergeConst(&E)操作結(jié)果:常數(shù)合并操作,合并表達(dá)式E中所有常數(shù)運(yùn)算。}ADTExpression3、整體設(shè)計(jì)在這個課程設(shè)計(jì)中,有兩個源代碼文件:expression.h和expression.c。在expression.h文件中,包含了各個存儲結(jié)構(gòu)的聲明和輔助存儲結(jié)構(gòu)的兩個棧的基本操作;在expression.c文件中,是實(shí)現(xiàn)課程設(shè)計(jì)要求的各個函數(shù)?!兑弧積xpression.h文件的整體結(jié)構(gòu)1、各個存儲結(jié)構(gòu)的聲明;2、兩個除了棧名和棧存儲的元素不一樣的順序棧的基本操作。其基本操作如下:對于棧SqStack:StatusInitStack(SqStack*S) /*構(gòu)造一個空棧S*/StatusStackEmpty(SqStackS) /*若棧S為空棧,則返回TRUE,否則返回FALSE*/StatusPush(SqStack*S,SElemTypee) /*插入元素e為新的棧頂元素*/StatusPop(SqStack*S,SElemType*e)/*若棧不空,則刪除S的棧頂元素,用e返回其值,并返回OK;否則返回ERROR*/StatusGetTop(SqStackS,SElemType*e)/*若棧不空,則用e返回S的棧頂元素,并返回OK;否則返回ERROR*/對于棧SqStack1:StatusInitStack1(SqStack1*S) /*構(gòu)造一個空棧S*/StatusStackEmpty1(SqStack1S) /*若棧S為空棧,則返回TRUE,否則返回FALSE*/StatusPush1(SqStack1*S,SElemType1e) /*插入元素e為新的棧頂元素*/StatusPop1(SqStack1*S,SElemType1*e) /*若棧不空,則刪除S的棧頂元素,用e返回其值,并返回OK;否則返回ERROR*/StatusGetTop1(SqStack1S,SElemType1*e)/*若棧不空,則用e返回S的棧頂元素,并返回OK;否則返回ERROR*/順序棧的基本操作的算法見程序清單。《二》expression.c文件的整體結(jié)構(gòu)1、主程序模塊的整體流程可以從主菜單函數(shù)可以明了的了解的程序的整體流程,主菜單函數(shù)menu()如下: charmenu() { charchoice; printf("\n****************************************"); printf("\n1>>>輸入正確的前綴表達(dá)式"); printf("\n2>>>帶括弧的中綴表示式輸出"); printf("\n3>>>對變量進(jìn)行賦值"); printf("\n4>>>對算數(shù)表達(dá)式求值"); printf("\n5>>>構(gòu)造一個新的復(fù)合表達(dá)式"); printf("\n6>>>以表達(dá)式的原書寫形式輸入"); printf("\n7>>>合并表達(dá)式中所有常數(shù)運(yùn)算"); printf("\n0>>>退出"); printf("\n****************************************"); printf("\n請輸入你的選擇>>>>>"); choice=getche(); returnchoice; }在主函數(shù)中,采用多分支程序設(shè)計(jì)語句switch()使程序產(chǎn)生不同的流向,從而達(dá)到實(shí)現(xiàn)課程設(shè)計(jì)的各個要求。voidmain(){ while(1) { 清屏; switch(主菜單) { 根據(jù)不同的選擇,調(diào)用不同的操作函數(shù),完成各個操作; } }}2、本程序有四個模塊,主程序模塊,二叉樹模塊,兩個順序棧模塊。四者的調(diào)用關(guān)系如下:主程序模塊二叉樹模塊主程序模塊二叉樹模塊順序棧SqStack模塊順序棧SqStack1模塊主程序模塊中的對于表達(dá)式的存儲結(jié)構(gòu)調(diào)用了二叉樹模塊,而在構(gòu)造表達(dá)式的二叉樹模塊中又調(diào)用了順序棧SqStack模塊,主程序中在將原表達(dá)式形式輸入表達(dá)式轉(zhuǎn)換為前綴表達(dá)式操作中調(diào)用了順序棧SqStack1模塊。四、【詳細(xì)設(shè)計(jì)】1、二叉樹的存儲類型/*二叉樹結(jié)點(diǎn)類型*/ typedefenum{INT,CHAR}ElemTag;/*INT為整型數(shù)據(jù)num,CHAR為字符型數(shù)據(jù)c*/ typedefstructTElemType { ElemTagtag;/*{INT,CHAR}指示是整型還是字符型*/ union { intnum;/*tag=INT時,為整型*/ charc;/*tag=CHAR時,為字符型*/ }; }TElemType; /*二叉樹的二叉鏈表存儲表示*/ typedefstructBiTNode { TElemTypedata; structBiTNode*lchild,*rchild;/*左右孩子指針*/ }BiTNode,*BiTree;二叉樹的基本操作已經(jīng)在構(gòu)造表達(dá)式和表達(dá)式中的基本操作中根據(jù)不同的功能和實(shí)際情況修改了,詳細(xì)見各個函數(shù)操作的算法設(shè)計(jì)。2、順序棧的存儲類型/*棧的順序存儲表示*/#defineSTACK_INIT_SIZE10/*存儲空間初始分配量*/#defineSTACKINCREMENT2/*存儲空間分配增量*//*兩個順序棧*/typedefstructSqStack { SElemType*base;/*在棧構(gòu)造之前和銷毀之后,base的值為NULL*/ SElemType*top;/*棧頂指針*/ intstacksize;/*當(dāng)前已分配的存儲空間,以元素為單位*/ }SqStack;/*順序棧SqStack*/typedefstructSqStack1 { SElemType1*base;/*在棧構(gòu)造之前和銷毀之后,base的值為NULL*/ SElemType1*top;/*棧頂指針*/ intstacksize;/*當(dāng)前已分配的存儲空間,以元素為單位*/ }SqStack1;/*順序棧SqStack1*/相關(guān)的基本操作見上面的“expression.h文件的整體結(jié)構(gòu)”的說明,詳細(xì)的算法設(shè)計(jì)見附錄的程序清單。3、表達(dá)式的基本操作StatusInput_Expr(char*string,intflag);/*以字符序列的形式輸入語法正確的前綴表達(dá)式,保存到字符串string*//*參數(shù)flag=0表示輸出的提示信息是"請輸入正確的前綴表示式:"*//*flag=1表示輸出的提示信息為"請以表達(dá)式的原書寫形式輸入正確表示式:"*/voidjudge_value(BiTree*E,char*string,inti);/*判斷字符string[i],如果是'0'-'9'常量之間,二叉樹結(jié)點(diǎn)存為整型;否則,存為字符型*/StatusReadExpr(BiTree*E,char*exprstring);/*以正確的前綴表示式并構(gòu)造表達(dá)式E*/StatusPri_Compare(charc1,charc2);/*如果兩個字符是運(yùn)算符,比較兩個運(yùn)算符的優(yōu)先級,c1比c2優(yōu)先,返回OK,否則返回ERROR*/voidWriteExpr(BiTreeE);/*用帶括弧的中綴表達(dá)式輸入表達(dá)式*/voidAssign(BiTree*E,charV,intc,int*flag);/*實(shí)現(xiàn)對表達(dá)式中的所有變量V的賦值(V=c),參數(shù)flag為表示是否賦值過的標(biāo)志*/longOperate(intopr1,charopr,intopr2);/*運(yùn)算符運(yùn)算求值,參數(shù)opr1,opr2為常量,opr為運(yùn)算符,根據(jù)不同的運(yùn)算符,實(shí)現(xiàn)不同的運(yùn)算,返回運(yùn)算結(jié)果*/StatusCheck(BiTreeE);/*檢查表達(dá)式是否還存在沒有賦值的變量,以便求算數(shù)表達(dá)式的值*/longValue(BiTreeE);/*對算術(shù)表達(dá)式求值*/voidCompoundExpr(charP,BiTree*E1,BiTreeE2);/*構(gòu)造一個新的復(fù)合表達(dá)式*/StatusRead_Inorder_Expr(char*string,char*pre_expr);/*以表達(dá)式的原書寫形式輸入,表達(dá)式的原書寫形式字符串string變?yōu)樽址畃re_expr,后調(diào)用reversal_string()函數(shù)反轉(zhuǎn)得到前綴表達(dá)式pre_expr*/voidMergeConst(BiTree*E);/*常數(shù)合并操作函數(shù),合并表達(dá)式E中所有常數(shù)運(yùn)算*/4、主程序和其他偽碼算法voidmain(){ while(1) { switch(menu()) { case'1':/*輸入正確的前綴表達(dá)式*/ if(Input_Expr(Expr_String,0))輸入正確的前綴表達(dá)式 if(ReadExpr(&E,Expr_String))構(gòu)造表達(dá)式 {flag=1;printf("\n表達(dá)式構(gòu)造成功!");} case'2':/*帶括弧的中綴表示式輸出*/ if(flag==1)WriteExpr(E); elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); case'3':/*對變量進(jìn)行賦值*/ if(flag==1) { flushall();/*清理緩沖區(qū)*/ V=getchar(); scanf(&c); Assign(&E,V,c,&Assign_flag); } elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); case'4':/*對算數(shù)表達(dá)式求值*/ if(flag==1) { if(Check(E)) {result=Value(E);WriteExpr(E);printf(result);} } elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); case'5':/*構(gòu)造一個新的復(fù)合表達(dá)式*/ if(flag==1) { flushall();/*清理緩沖區(qū)*/ if(Input_Expr(string,1)) { if(Read_Inorder_Expr(string,Expr_String)) {/*按原表達(dá)式形式輸入*/ reversal_string(Expr_String); if(ReadExpr(&E1,Expr_String)) {flag=1;P=getchar(); CompoundExpr(P,&E,E1); } elseprintf("\n復(fù)合新的表達(dá)式失??!請按任意鍵返回主菜單!");}}} case'6':/*以表達(dá)式的原書寫形式輸入*/ if(Input_Expr(string,1)) if(Read_Inorder_Expr(string,Expr_String)) { reversal_string(Expr_String); if(ReadExpr(&E,Expr_String)) {flag=1;printf("\n表達(dá)式構(gòu)造成功!");} } case'7':/*合并表達(dá)式中所有常數(shù)運(yùn)算*/ if(flag==1)MergeConst(&E);case'8'://三角函數(shù)操作 printf("\n\t***************************三角函數(shù)操作(選作)***************************"); printf("\n"); printf("\n\t[注]請按要求輸入其中~代表sin!代表cos@代表tan");printf("\n\t角度用弧度表示,例如~1即表示sin1");printf("\n\t本操作只可求三角函數(shù)值,如需其他操作請將結(jié)果帶入其它操作中");printf("\n\t輸入一個字符請按回車,確保正確錄入");printf("\n\t************************************************************************");doubleopr1,result1; charopr; printf("\n請按要求輸入"); scanf("%c",&opr);getch(); scanf("%lf",&opr1);getch();result1=Operate1(opr,opr1); printf("結(jié)果為%f",result1); getch();break; case'0':/*退出*/}}}5、函數(shù)的調(diào)用關(guān)系除了主函數(shù)main()外,其他各個函數(shù)相對于其它函數(shù)來說是獨(dú)立的,函數(shù)的使用都由主函數(shù)main()調(diào)用使用的,可以簡單的說,各個函數(shù)都是主函數(shù)下的從函數(shù)。五、【設(shè)計(jì)分析】1,開始設(shè)計(jì)時我設(shè)想建樹時可以設(shè)定五個域,左右孩子,標(biāo)志tag,int型值域,char型值域。但是在存儲時發(fā)現(xiàn)每個字符只需占一個域就可以,所以我又采用共同體這樣節(jié)約了內(nèi)存。2.在算法設(shè)計(jì)中,構(gòu)造表達(dá)式樹的時候,本來以為使用遞歸構(gòu)造表達(dá)式會很難做到出錯處理的,所以采用了順序棧輔助構(gòu)造方法,并且盡可能地對程序進(jìn)行完善,出錯處理。但是經(jīng)過與同學(xué)的相互討論和研究,發(fā)現(xiàn)自己的想法犯了很大的錯誤,遞歸構(gòu)造表達(dá)式對于出錯處理很簡單也很完善,這一點(diǎn)讓我加深了遞歸的使用和理解。3.也就是三角函數(shù)問題,我最頭疼的地方。首先開始運(yùn)行時會出現(xiàn)錯誤,無法輸出正確結(jié)果。通過網(wǎng)上搜索,我發(fā)現(xiàn)對于三角函數(shù)的定義類型必須是double,這樣的話,如果要改的話,差不多改大半程序,所以我就讓此功能單獨(dú)出來,由提示讓用戶手動完成。4、在調(diào)試的過程中,花費(fèi)時間最為多的是對輸入錯誤表達(dá)式的出錯處理,更改增加的代碼幾乎都是為了出錯處理,但是,覺得這樣的調(diào)試才更能鍛煉一個人的編程能力。六、【調(diào)試分析】1.進(jìn)入演示程序主界面2.第一次輸入,需要選擇1功能《一》選擇‘1’進(jìn)入測試輸入正確的前綴表達(dá)式操作1、輸入的前綴表達(dá)式為一個不大于9常量:‘8’2、輸入前綴表達(dá)式為一個變量:‘Z’3、輸入前綴表達(dá)式為一個簡單的運(yùn)算表達(dá)式:‘-91’4、輸入前綴表達(dá)式為一個較為復(fù)雜的、帶有變量的表達(dá)式:‘+++*3^x3*2^x2x6’5、輸入前綴表達(dá)式‘*-+23a+b*34’,輸出帶括弧的表達(dá)式6、輸入錯誤的前綴表達(dá)式:‘+999’和‘+*5^x2*8x&’ 《二》選擇‘3’進(jìn)入測試對變量的賦值1、對前綴表達(dá)式‘3*x^3+2*x^2+x+6’中變量x進(jìn)行賦值,賦值為52、對前綴表達(dá)式‘a(chǎn)+b*c’中的變量b進(jìn)行賦值,賦值為63、對前綴表達(dá)式‘5*x^2+8*x’中不存在的變量y進(jìn)行賦值,賦值為4《三》選擇‘4’進(jìn)入測試求算數(shù)表達(dá)式的值1、求算數(shù)表達(dá)式‘9+8’的值2、求算數(shù)表達(dá)式‘(65+98)*(9^2+(21-96))’的值3、求仍存在變量的表達(dá)式‘3+a*9-6’的值《四》選擇‘5’進(jìn)入構(gòu)造新的復(fù)合表達(dá)式1、未構(gòu)造表達(dá)式E時2、已構(gòu)造了表達(dá)式E時《五》選擇‘6’進(jìn)入以原表達(dá)式形式輸入構(gòu)造表達(dá)式1、構(gòu)造表達(dá)式‘6*a+9/b-(a+2^3)’輸出的結(jié)果少了括弧,這個是程序中的一個BUG,程序的判定帶括弧輸出表達(dá)式時判斷兩個優(yōu)先級別時的一個很大的BUG,一個本人自己沒法解決的BUG。2、構(gòu)造表達(dá)式‘(((3+2)*9)-(6/3)*9+1)/8+18*3’輸出的結(jié)果簡化了多余的括弧,這一點(diǎn)是一個很大的優(yōu)化。3、構(gòu)造表達(dá)式‘66++’,出錯處理4、構(gòu)造表達(dá)式‘6+-b+9*9’,出錯處理5、構(gòu)造表達(dá)式‘9+a+(6+5))*a’,出錯處理多余輸入的括弧6、構(gòu)造表達(dá)式‘6#9+8*6’,出錯處理輸入非運(yùn)算符和非變量常量的表達(dá)式《六》選擇‘7’進(jìn)入合并常數(shù)操作1、構(gòu)造表達(dá)式‘(2+3-a)*(b+3*4)’,后合并常數(shù)操作2、構(gòu)造表達(dá)式‘(3+3*4)*(1*2+8/2)’,經(jīng)過多次合并,得出最后結(jié)果這個合并常數(shù)操作唯一的缺點(diǎn)就是要多次操作,但是,這個缺點(diǎn)也不能說為缺點(diǎn),它可以很清晰的反映出表達(dá)式求值的步驟!《七》選擇‘8’,進(jìn)入三角函數(shù)操作經(jīng)過對各個操作的測試,可以這樣總結(jié)的說,基本完成了課程設(shè)計(jì)的要求,雖說其中有一些操作還存在BUG需要去完善改進(jìn)。七、【實(shí)驗(yàn)心得】1經(jīng)過這兩周的編譯,我感覺對二叉樹的掌握更牢固了,整體上我都是用的二叉樹處理實(shí)現(xiàn)各個功能。我感覺對于一個題目中處理函數(shù)盡量讓他可以多功能中使用,這樣編程效率會高一些。2.我開始設(shè)計(jì)的時候只考慮一個功能一個功能的實(shí)現(xiàn)。這樣做很沒有全局觀念。我認(rèn)為在以后的編程中一定要有全局意識,整體上構(gòu)思好,有個好的數(shù)據(jù)結(jié)構(gòu),這樣事半功倍。3.編程就是要多動手八、【參考文獻(xiàn)】嚴(yán)蔚敏,吳偉民著,數(shù)據(jù)結(jié)構(gòu)(C語言版),北京:清華大學(xué)出版社,2007附源代碼expression.cpp #include"expression.h"#include"math.h"#include<stdio.h>//#include<stdlib.h>/*全局變量*/ intsave_number[51];/*在按原表達(dá)式輸入形式中,輸入的常量保存到數(shù)組save_number中,常量最多為50個,0單元不用*/ charExpr_String[50];/*存放表達(dá)式的字符串*/ /*以字符序列的形式輸入語法正確的前綴表達(dá)式,保存到字符串string*/ /*參數(shù)flag=0表示輸出的提示信息是"請輸入正確的前綴表示式:"*/ /*flag=1表示輸出的提示信息為"請以表達(dá)式的原書寫形式輸入正確表示式:"*/ StatusInput_Expr(char*string,intflag) { if(flag==0)printf("\n請輸入正確的前綴表示式:"); elseprintf("\n請以表達(dá)式的原書寫形式輸入正確表示式:"); flushall();/*清理緩沖區(qū)*/ gets(string);/*從鍵盤輸入一串字符串作為表達(dá)式*/ if(strlen(string)==1)/*輸入的表達(dá)式字符串長度為1*/ if(string[0]=='+'||string[0]=='-'||string[0]=='*'||string[0]=='/'||string[0]=='^')/*輸入的表達(dá)式只有一個運(yùn)算符*/ {printf("\n表達(dá)式只有一個字符,為運(yùn)算符,錯誤!");returnERROR;} elseif((string[0]>='0'&&string[0]<'9')||(string[0]>='a'&&string[0]<='z')||(string[0]>='A'&&string[0]<='Z')) /*輸入的表達(dá)式只有一個數(shù)字或字符*/ {printf("\n表達(dá)式只有一個字符!");returnOK;} else{printf("\n輸入的字符不是運(yùn)算符也不是變量常量,錯誤!");returnERROR;} returnOK; } /*判斷字符string[i],如果是'0'-'9'常量之間,二叉樹結(jié)點(diǎn)存為整型;否則,存為字符型*/ voidjudge_value(BiTree*E,char*string,inti) { if(string[i]>='0'&&string[i]<='9')/*為常量*/ {(*E)->data.tag=INT;(*E)->data.num=string[i]-48;} elseif(string[i]>=1&&string[i]<=20)/*為常量,常量存于數(shù)組save_number中*/ {(*E)->data.tag=INT;(*E)->data.num=save_number[string[i]];} else/*為變量*/ {(*E)->data.tag=CHAR;(*E)->data.c=string[i];} } /*以正確的前綴表示式并構(gòu)造表達(dá)式E*/ StatusReadExpr(BiTree*E,char*exprstring) { SqStackS;//定義順序棧S inti,len;/*len為表達(dá)式的長度*/ BiTreep,q; (*E)=(BiTree)malloc(sizeof(BiTNode));/*申請二叉樹的根結(jié)點(diǎn)的空間*/ (*E)->lchild=NULL; (*E)->rchild=NULL; len=strlen(exprstring);/*len賦值為表達(dá)式的長度*/ if(len==1)/*表達(dá)式長度為1時,二叉樹只有根結(jié)點(diǎn)*/ judge_value(E,exprstring,0);/*將exprstring[0]存入二叉樹的結(jié)點(diǎn)中*/ else { judge_value(E,exprstring,0);/*將exprstring[0]存入二叉樹的結(jié)點(diǎn)中*/ InitStack(&S);/*初始化棧*/ q=(*E); Push(&S,q);/*入棧*/ Push(&S,q);/*入棧,根結(jié)點(diǎn)入棧兩次是為判斷先序輸入的表達(dá)式是不是正確的表達(dá)式*/ for(i=1;i<len&&!StackEmpty(S);i++)// { p=(BiTree)malloc(sizeof(BiTNode)); judge_value(&p,exprstring,i);/*將exprstring[i]存入二叉樹的結(jié)點(diǎn)中*/ p->lchild=NULL; p->rchild=NULL; if(exprstring[i]=='+'||exprstring[i]=='-'||exprstring[i]=='*'||exprstring[i]=='/'||exprstring[i]=='^') {/*為運(yùn)算符,運(yùn)算符入棧,左孩子不空,向左孩子走,否則,如果右孩子不空,向右孩子走*/ if(!q->lchild) {q->lchild=p;Push(&S,p);q=p;} else {q->rchild=p;Push(&S,p);q=p;} } else/*不是運(yùn)算符,運(yùn)算符出棧*/ { if(!q->lchild) {q->lchild=p;Pop(&S,&q);} else {q->rchild=p;Pop(&S,&q);} } } if(StackEmpty(S)&&i>=len) returnOK;/*??涨襥>=len,說明輸入的表達(dá)式是正確的*/ else /*輸入的表達(dá)式是錯誤的*/ { printf("\n輸入的表達(dá)式有誤!"); returnERROR; } } } /*如果兩個字符是運(yùn)算符,比較兩個運(yùn)算符的優(yōu)先級,c1比c2優(yōu)先,返回OK,否則返回ERROR*/ StatusPri_Compare(charc1,charc2) { if((c1=='^'||c1=='*'||c1=='-'||c1=='+'||c1=='/')&&(c2=='^'||c2=='*'||c2=='-'||c2=='+'||c2=='/')) {/*c1和c2為運(yùn)算符*/ if(c1=='^')/*c1為指數(shù)運(yùn)算符,則當(dāng)c2不為'^'時,c1比c2優(yōu)先*/ { if(c2!='^')returnOK; elsereturnERROR; } elseif(c1=='*'||c1=='/')/*c1為乘法或除法運(yùn)算符,則當(dāng)c2為'+'或'-',c1比c2優(yōu)先*/ { if(c2=='^'||c2=='*'||c2=='/')returnERROR; elsereturnOK; } elsereturnERROR;/*其余,c1不比c2優(yōu)先*/ } elsereturnERROR;/*c1和c2不是運(yùn)算符*/ } /*用帶括弧的中綴表達(dá)式輸出表達(dá)式*/ voidWriteExpr(BiTreeE) { if(E)/*樹不為空*/ { /*先遞歸左子樹*/ if(E->lchild&&E->lchild->data.tag==CHAR)/*E的左孩子不為空,且左孩子為字符*/ { if(Pri_Compare(E->data.c,E->lchild->data.c))/*E->data.c比E->lchild->data.c優(yōu)先*/ {printf("("); WriteExpr(E->lchild); printf(")");}/*帶括弧輸出左子樹*/ elseWriteExpr(E->lchild);/*否則,不帶括弧輸出左子樹*/ } elseWriteExpr(E->lchild);/*否則,輸出左子樹*/ /*訪問輸出根結(jié)點(diǎn)的值*/ if(E->data.tag==INT){printf("%d",E->data.num);} elseprintf("%c",E->data.c); /*后遞歸右子樹*/ if(E->rchild&&E->rchild->data.tag==CHAR)/*E的右孩子不為空,且右孩子為字符*/ { if(Pri_Compare(E->data.c,E->rchild->data.c))/*E->data.c比E->rchild->data.c優(yōu)先*/ {printf("(");WriteExpr(E->rchild);printf(")");}/*帶括弧輸出右子樹*/ elseWriteExpr(E->rchild);/*否則,不帶括弧輸出右子樹*/ } elseWriteExpr(E->rchild);/*否則,輸出右子樹*/ } } /*實(shí)現(xiàn)對表達(dá)式中的所有變量V的賦值(V=c),參數(shù)flag為表示是否賦值過的標(biāo)志*/ voidAssign(BiTree*E,charV,intc,int*flag) { if(*E) { if((*E)->data.tag==CHAR&&(*E)->data.c==V)/*如果找到要賦值的變量,賦值*/ {(*E)->data.tag=INT;(*E)->data.num=c;*flag=1;} Assign(&((*E)->lchild),V,c,flag);/*遞歸左子樹*/ Assign(&((*E)->rchild),V,c,flag);/*遞歸左子樹*/ } } /*指數(shù)運(yùn)算函數(shù),底數(shù)為x,指數(shù)為exp*/ longpower(intx,intexp) { longresult; inti; for(i=1,result=1;i<=exp;i++) result*=x; returnresult; } /*運(yùn)算符運(yùn)算求值,參數(shù)opr1,opr2為常量,opr為運(yùn)算符,根據(jù)不同的運(yùn)算符,實(shí)現(xiàn)不同的運(yùn)算,返回運(yùn)算結(jié)果*/ longOperate(intopr1,charopr,intopr2) { longresult; switch(opr) { case'+':/*加法*/ result=opr1+opr2; returnresult;break; case'-':/*減法*/ result=opr1-opr2; returnresult;break; case'*':/*乘法*/ result=opr1*opr2; returnresult;break; case'/':/*除法,除法是在整型類型上的除法*/ result=opr1/opr2; returnresult;break; case'^':/*指數(shù)運(yùn)算*/ result=power(opr1,opr2); returnresult;break; default:break; } } /*運(yùn)算符運(yùn)算求值,參數(shù)opr為常量,opr1為運(yùn)算符,根據(jù)不同的運(yùn)算符,實(shí)現(xiàn)不同的運(yùn)算,返回運(yùn)算結(jié)果*/ doubleOperate1(charopr,doubleopr1) { doubleresult1; switch(opr) { case'~':/*正玄sin*/ result1=sin(opr1); returnresult1;break;case'!':/*余弦*/ result1=cos(opr1); returnresult1;break;case'@':/*正切*/ result1=tan(opr1); returnresult1;break; default:break; } } /*檢查表達(dá)式是否還存在沒有賦值的變量,以便求算數(shù)表達(dá)式的值*/ StatusCheck(BiTreeE) { if(E&&E->data.tag==CHAR)/*樹不為空*/ { if(E->data.c!='*'&&E->data.c!='^'&&E->data.c!='-'&&E->data.c!='+'&&E->data.c!='/') {printf("\n表達(dá)式中仍存在變量沒有賦值!沒法求出表達(dá)式的值!");returnERROR;} /*存在變量,提示信息,后返回ERROR*/ if(Check(E->lchild))/*遞歸左子樹*/ Check(E->rchild);/*遞歸右子樹*/ } } /*對算術(shù)表達(dá)式求值*/ longValue(BiTreeE) { if(E)/*樹不為空*/ { if(!E->lchild&&!E->rchild&&E->data.tag==INT)return(E->data.num); /*結(jié)點(diǎn)的左孩子和右孩子為空,為葉子結(jié)點(diǎn),返回結(jié)點(diǎn)的值*/ returnOperate(Value(E->lchild),E->data.c,Value(E->rchild)); /*運(yùn)算求值,后根遍歷的次序?qū)Ρ磉_(dá)式求值,其中參數(shù)遞歸調(diào)用了Value()函數(shù)求左子樹的值和右子樹的值*/ } } /*構(gòu)造一個新的復(fù)合表達(dá)式*/ voidCompoundExpr(charP,BiTree*E1,BiTreeE2) { BiTreeE; E=(BiTree)malloc(sizeof(BiTNode));/*申請一個結(jié)點(diǎn)存放運(yùn)算符P*/ E->data.tag=CHAR; E->data.c=P;/*申請到的結(jié)點(diǎn)值為P*/ E->lchild=(*E1);/*結(jié)點(diǎn)的左孩子為E1*/ E->rchild=E2;/*結(jié)點(diǎn)的右孩子為E2*/ (*E1)=E;/*(*E1)為根結(jié)點(diǎn)*/ printf("\n表達(dá)式E復(fù)合成功!其表達(dá)式變?yōu)椋篭n"); WriteExpr(E);/*輸出復(fù)合好的表達(dá)式*/ } /*以表達(dá)式的原書寫形式輸入,表達(dá)式的原書寫形式字符串string變?yōu)樽址畃re_expr*/ /*后調(diào)用reversal_string()函數(shù)反轉(zhuǎn)得到前綴表達(dá)式pre_expr*/ StatusRead_Inorder_Expr(char*string,char*pre_expr) { inti,j,len,char_number=1;/*len表示字符串string的長度,char_number是記錄數(shù)組save_number[]的個數(shù)*/ intnumber;/*保存大于9的常量*/ charc,c1; SqStack1S;/*棧定義*/ InitStack1(&S);/*初始棧*/ Push1(&S,'#');/*先將字符'#'入棧,用來表示作為棧的最底一個元素*/ len=strlen(string);/*len為字符串string的長度*/ c=string[len-1];/*從字符串的最后一個字符開始向前掃描*/ i=len-1; while(!StackEmpty1(S)&&i>=0)/*棧不為空且i大于等于0*/ { if(c=='(')/*字符為'('*/ { Pop1(&S,&c);/*出棧,賦值給c*/ while(c!=')')/*假如c不為')',出棧*/ { *pre_expr++=c; if(!StackEmpty1(S)&&GetTop1(S,&c1)&&c1!='#')Pop1(&S,&c); else{printf("\n輸入的表達(dá)式有誤!");returnERROR;} } } elseif(c==')')/*字符為')',入棧*/ { Push1(&S,c); } elseif(c>='0'&&c<='9')/*字符為'0'-'9'之間,循環(huán)掃描string前一個字符,后確定常量的大小*/ { number=c-48;/*number為第一個常量字符的ASCII碼-48*/ for(c1=string[i-1],j=1;(c1>='0'&&c1<='9')&&i>=0;j++,i--)/*循環(huán)掃描string前一個字符,求出常量后賦給number*/ { number=(c1-48)*power(10,j)+number;/*number為掃描到的常量*/ c1=string[i-2]; } save_number[char_number]=number;/*將number存入到數(shù)組save_number中,下標(biāo)為char_number*/ *pre_expr++=char_number++; } elseif((c>='a'&&c<='z')||(c>='A'&&c<='Z'))/*字符為'a'-'z'或'A'-'Z'之間的變量*/ {/*string下一個字符不能為常量或變量,否則,出錯*/ if((string[i-1]>='0'&&string[i-1]<='9')||(string[i-1]>='A'&&string[i-1]<='Z')||(string[i-1]>='a'&&string[i-1]<='z')) {printf("\n輸入的表達(dá)式有誤!");returnERROR;} else *pre_expr++=c; } elseif(c=='*'||c=='/')/*字符為運(yùn)算符'*'或'/'*/ { while(GetTop1(S,&c1)&&(c1=='^'))/*將c與棧頂?shù)淖址鹀1比較優(yōu)先級*/ {Pop1(&S,&c1);*pre_expr++=c1;}/*如果c1比c優(yōu)先,出棧*/ Push1(&S,c);/*入棧字符c*/ } elseif(c=='+'||c=='-')/*字符為運(yùn)算符'+'或'-'*/ { while(GetTop1(S,&c1)&&(c1=='^'||c1=='*'||c1=='/'))/*將c與棧頂?shù)淖址鹀1比較優(yōu)先級*/ {Pop1(&S,&c1);*pre_expr++=c1;}/*如果c1比c優(yōu)先,出棧*/ Push1(&S,c);/*入棧運(yùn)算符c*/ } elseif(c=='^')/*字符為運(yùn)算符'^'*/ { Push1(&S,c);/*入棧運(yùn)算符'^'*/ } else{printf("\n輸入的表達(dá)式有誤!");returnERROR;}/*其他字符,錯誤,返回ERROR*/ i--;/*下一個字符*/ if(i>=0)c=string[i];/*i不小于0,c=string[i]循環(huán)下一個字符*/ else/*否則,將清空棧*/ while(!StackEmpty1(S)&&GetTop1(S,&c1)&&c1!='#') {Pop1(&S,&c);*pre_expr++=c;} } Pop1(&S,&c);/*將'#'出棧*/ *pre_expr='\0';/*字符串結(jié)束符*/ if(i<0&&StackEmpty1(S))returnOK; elsereturnERROR; } /*將字符串exprstring反轉(zhuǎn)過來*/ voidreversal_string(char*exprstring) { intlen,i,j; chartemp; len=strlen(exprstring);/*len為exprstring的長度*/ for(i=0,j=len-1;i<j;i++,j--)/*字符串前后兩個字符對換*/ { temp=exprstring[i]; exprstring[i]=exprstring[j]; exprstring[j]=temp; } } /*常數(shù)合并操作函數(shù),合并表達(dá)式E中所有常數(shù)運(yùn)算*/ voidMergeConst(BiTree*E) { longresult; if((*E)->lchild&&(*E)->rchild)/*左右孩子不為空*/ { if((*E)->lchild->data.tag==INT&&(*E)->rchild->data.tag==INT)/*假如左右孩子為常量,合并*/ { result=Operate((*E)->lchild->data.num,(*E)->data.c,(*E)->rchild->data.num);/*常數(shù)合并運(yùn)算,調(diào)用Operate()函數(shù)求值*/ (*E)->data.tag=INT;(*E)->data.num=result;/*修改之前的運(yùn)算符為常量*/ free((*E)->lchild);/*釋放左孩子*/ free((*E)->rchild);/*釋放右孩子*/ (*E)->lchild=(*E)->rchild=NULL;/*左右孩子置空*/ } else { MergeConst(&((*E)->lchild));/*遞歸左孩子*/ MergeConst(&((*E)->rchild));/*遞歸右孩子*/ } } }//判斷是否操作符intisoperator(charc){switch(c){case'+':returnTRUE;case'-':returnTRUE;case'*':returnTRUE;case'/':returnTRUE;case'^':returnTRUE;default:returnFALSE;}}voidDiff(BiTree&E,charv)//求偏導(dǎo)數(shù){/*第一種情況帶乘方的 if(((*E)->lchild)&&((*E)->rchild)) { if((*E)->data.tag==CHAR&&(*E)->rchild->lchild->data.tag==CHAR) if(((*E)->rchild->data.c=='^')&&((*E)->rchild->lchild->data.c==v)) { (*E)->lchild->data.num=((*E)->lchild->data.num)*((*E)->rchild->rchild->data.num); (*E)->rchild->rchild->data.num=(*E)->rchild->rchild->data.num-1; } //第二種只帶單次方//第三種只為常數(shù)*/// intd,flag3;//printf("%c",v); if((E->lchild)&&(E->rchild)) { if((E->rchild->data.c=='^')&&(E->rchild->lchild->data.c==v)) { E->lchild->data.num=(E->lchild->data.num)*(E->rchild->rchild->data.num); E->lchild->data.tag=INT; E->rchild->rchild->data.num=E->rchild->rchild->data.num-1; } if(E->rchild->data.tag==INT&&(E->data.c=='+'||E->data.c=='-')) { E->rchild->data.num=0; E->rchild->data.tag=INT; } if((E->rchild->data.c==v)&&(isoperator(E->lchild->data.c))) { E->rchild->data.num=1; E->rchild->data.tag=INT;// Diff(E->lchild,v);// Diff(E->rchild,v); } if((E->rchild->data.c==v)&&E->lchild->data.tag==INT) { E->data.num=E->lchild->data.num; E->data.tag=INT; free(E->lchild); free(E->rchild); E->lchild=E->rchild=NULL; } else { Diff(E->lchild,v); Diff(E->rchild,v); } }// else// {// printf("表達(dá)式不需要求偏導(dǎo)\n");// } } /*主菜單*/ charmenu() { charchoice; printf("\n\t****************************************"); printf("\n\t***********9.表達(dá)式類型的實(shí)現(xiàn)***********"); printf("\n\t1>>>輸入正確的前綴表達(dá)式"); printf("\n\t2>>>帶括弧的中綴表示式輸出"); printf("\n\t3>>>對變量進(jìn)行賦值"); printf("\n\t4>>>對算數(shù)表達(dá)式求值"); printf("\n\t5>>>構(gòu)造一個新的復(fù)合表達(dá)式"); printf("\n\t6>>>以表達(dá)式的原書寫形式輸入(選作)"); printf("\n\t7>>>合并表達(dá)式中所有常數(shù)運(yùn)算(選作)");printf("\n\t8>>>三角函數(shù)操作(選作)");//printf("\n\t9>>>求偏導(dǎo)數(shù)(選作)"); printf("\n\t0>>>退出"); printf("\n\t****************************************"); printf("\n\t請輸入你的選擇(數(shù)字)>>>>>"); choice=getche(); returnchoice; } /*主函數(shù)*/ voidmain() { BiTreeE,E1;/*兩個表達(dá)式E和E1*/ intflag=0;/*表達(dá)式E構(gòu)造標(biāo)志,為0表示未構(gòu)造,為1表示已構(gòu)造*/ longresult;/*保存算數(shù)表達(dá)式運(yùn)算結(jié)果*/ charV,P;//V被賦值,P為符合表達(dá)式運(yùn)算符 intc;//C要賦值 charstring[30];//字符串 while(1) { system("cls");//清屏 switch(menu()) { case'1':/*1>>>輸入正確的前綴表達(dá)式*/ printf("\n\t*************************輸入提示信息************************"); printf("\n\t輸入正確的前綴表達(dá)式的要求:"); printf("\n\t\t【變量】a-z或A-Z"); printf("\n\t\t【常量】0-9,不能超過9"); printf("\n\t\t【運(yùn)算符】+,-,*,/,^(乘冪)"); printf("\n\t\t例0;5;+a*53"); printf("\n\t請輸入正確的前綴表達(dá)式,后按回車鍵存入緩沖區(qū),否則可能會出錯!"); printf("\n\t*************************************************************"); if(Input_Expr(Expr_String,0))//在flag=0時,初始輸入 if(ReadExpr(&E,Expr_String))//前綴讀入并構(gòu)造E {flag=1; printf("\n表達(dá)式構(gòu)造成功!\n輸入的帶括弧的中綴表達(dá)式:"); WriteExpr(E);}/*帶括弧的中綴表示式輸出,遞歸實(shí)現(xiàn)*/ getch(); break; case'2':/*2>>>帶括弧的中綴表示式輸出*/ printf("\n\t********************輸出說明信息***********************************"); printf("\n\t輸出帶括弧的中綴表達(dá)式:"); printf("\n\t【1】如果表達(dá)式已經(jīng)構(gòu)造成功的,輸出表達(dá)式;"); printf("\n\t【2】如果表達(dá)式還未構(gòu)造成功的,請返回主菜單選擇構(gòu)造表達(dá)式;"); printf("\n\t【注】其中要注意的是,可能有一些表達(dá)式構(gòu)造時沒有辦法判斷為有誤,"); printf("\n\t如果輸出不是你想得到的,說明你之前輸入的表達(dá)式有誤,請重新構(gòu)造!"); printf("\n\t********************************************************************"); if(flag==1) {printf("\n帶括弧的中綴表達(dá)式為:"); WriteExpr(E); } elseprintf("\n表達(dá)式未構(gòu)造成功!請重新構(gòu)造成功的表達(dá)式!"); getch(); break; case'3':/*3>>>對變量進(jìn)行賦值*/ printf("\n\t********************賦值操作說明信息***********************************"); printf("\n\t賦值操作:實(shí)現(xiàn)對表達(dá)式中的某一個變量V的賦值,即使V=C,C為一整數(shù)"); printf("\n\t【1】根據(jù)輸出的表達(dá)式,輸入要賦值的變量V,只能輸入一個字符,否則出錯"); printf("\n\t【2】輸入要將變量V賦值為的整數(shù)C,只能是整數(shù),否則出錯"); printf("\n\t【注】如果表達(dá)式未構(gòu)造,請回到主菜單選擇構(gòu)造表達(dá)式"); printf("\n\t***********************************************************************"); if(flag==1) { intAssign_flag=0; printf("\n表達(dá)式E為:"); WriteExpr(E); flushall();/*清理緩沖區(qū)*/ printf("\n請輸入要賦值的字符:"); V=getchar(); printf("請輸入要將賦值為:"); scanf("%d",&c); Assign(&E,V,c,&Assign_flag);//賦值并改變標(biāo)志 if(Assign_flag) {printf("\n賦值成功!\n賦值后的表達(dá)式為:");WriteExpr(E);} elseprintf("\n表達(dá)式里沒有%c這個變量!",V); } elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); getch(); break; case'4':/*4>>>對算數(shù)表達(dá)式求值*/ printf("\n\t********************算數(shù)表達(dá)式求值說明信息************************"); printf("\n\t【注】如果表達(dá)式還有變量未賦值,即表達(dá)式不是算數(shù)表達(dá)式"); printf("\n\t不能求出表達(dá)式的值,請回到主菜單選擇賦值操作,后再求值"); printf("\n\t******************************************************************"); if(flag==1) { printf("\n算數(shù)表達(dá)式:");WriteExpr(E); if(Check(E))//檢查是否全賦值 {result=Value(E);printf("\n求算數(shù)表達(dá)式的值:\t");WriteExpr(E);printf("=%ld",result);} } elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); getch(); break; case'5':/*5>>>構(gòu)造一個新的復(fù)合表達(dá)式*/ printf("\n\t*****************構(gòu)造新的復(fù)合表達(dá)式說明信息***************************"); printf("\n\t【1】構(gòu)造一個新的表達(dá)式E1,采用表達(dá)式的原書寫形式輸入"); printf("\n\t【2】構(gòu)造表達(dá)式E1成功后,輸入要復(fù)合表達(dá)式E和E1的操作運(yùn)算符(+,-,*,/,^)"); printf("\n\t【注】如表達(dá)式E未構(gòu)造,不能復(fù)合表達(dá)式;如構(gòu)造表達(dá)式E1錯誤,復(fù)合失敗"); printf("\n\t***********************************************************************"); if(flag==1) { printf("\n表達(dá)式E1為:"); WriteExpr(E); printf("\n請構(gòu)造新的表達(dá)式E2:"); flushall();/*清理緩沖區(qū)*/ if(Input_Expr(string,1))//標(biāo)志為1,輸入字符串 { if(Read_Inorder_Expr(string,Expr_String))//入棧 { reversal_string(Expr_String);//反轉(zhuǎn) if(ReadExpr(&E1,Expr_String)) { flag=1;printf("\n表達(dá)式E1構(gòu)造成功!");WriteExpr(E1); printf("\n請輸入要構(gòu)造新的復(fù)合表達(dá)式的操作運(yùn)算符>>>"); P=getchar(); while(P!='*'&&P!='/'&&P!='+'&&P!='-'&&P!='^') { flushall();/*清理緩沖區(qū)*/ printf("\n輸入的操作運(yùn)算符有誤!請重新輸入>>>"); P=getchar(); } CompoundExpr(P,&E,E1); } elseprintf("\n復(fù)合新的表達(dá)式失??!請按任意鍵返回主菜單!"); } } } elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); getch(); break; case'6':/*6>>>以表達(dá)式的原書寫形式輸入*/ printf("\n\t*************以表達(dá)式的原書寫形式輸入說明信息************************"); printf("\n\t輸入正確的原書寫形式表達(dá)式"); printf("\n\t【變量】a-z或A-Z"); printf("\n\t【常量】大于等于0的正整數(shù)"); printf("\n\t【運(yùn)算符】+,-,*,/,^(乘冪)"); printf("\n\t【括弧】左括弧(,右括弧)"); printf("\n\t【注】表示式中常量最多只能是30個,超過30個,出錯!"); printf("\n\t按原書寫形式輸入中,請按照正確的方式輸入,否則可能會出錯!"); printf("\n\t**********************************************************************"); if(Input_Expr(string,1)) if(Read_Inorder_Expr(string,Expr_String)) { reversal_string(Expr_String); if(ReadExpr(&E,Expr_String)) {flag=1;printf("\n表達(dá)式構(gòu)造成功!\n輸入的帶括弧的中綴表達(dá)式:");WriteExpr(E);} } getch(); break; case'7':/*7>>>合并表達(dá)式中所有常數(shù)運(yùn)算*/ printf("\n***************合并表達(dá)式中的所有常數(shù)運(yùn)算*******************************"); printf("\n【注】合并表達(dá)式中的所有常數(shù)運(yùn)算并不能一次性將常數(shù)都合并!"); printf("\n例如:表達(dá)式'1+2*(3+3*4+9/3)'的常數(shù)合并,選擇7進(jìn)行合并,結(jié)果變?yōu)閈n'1+2*(3+12+3)',"); printf("根據(jù)優(yōu)先級先后合并的,如果要合并到最后,需多次選擇7\n進(jìn)行合并,又合并一次'1+2*(15+3)',"); printf("再次合并'1+2*18',再次合并'1+36',\n再次合并'37',后無法合并!"); printf("\n************************************************************************"); if(flag==1) { printf("\n原表達(dá)式為:"); WriteExpr(E); MergeConst(&E);//常數(shù)合并操作 printf("\n合并表達(dá)式中所有的常數(shù)運(yùn)算后的表達(dá)式:"); WriteExpr(E); } elseprintf("\n表達(dá)式未構(gòu)造成功!請構(gòu)造成功的表達(dá)式!"); getch(); break; case'8'://三角函數(shù)操作 printf("\n\t***************************三角函數(shù)操作(選作)***************************"); printf("\n"); printf("\n\t[注]請按要求輸入其中~代表sin!代表cos@代表tan");printf("\n\t角度用弧度表示,例如~1即表示sin1");printf("\n\t本操作只可求三角函數(shù)值,如需其他操作請將結(jié)果帶入其它操作中");printf("\n\t輸入一個字符請按回車,確保正確錄入");
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度新能源汽車充電樁設(shè)備采購合同協(xié)議書
- 2024婦女節(jié)活動中班(6篇)
- 2025年江西省高三語文2月統(tǒng)一調(diào)研聯(lián)考試卷附答案解析
- 河北省高職單招2024年數(shù)學(xué)真題仿真卷
- 2025年全球貿(mào)易合同樣式
- 2025年車載高壓空壓機(jī)組項(xiàng)目提案報(bào)告模范
- 2025年鐵礦石采選項(xiàng)目立項(xiàng)申請報(bào)告模范
- 2025年勞動力輸入安全保障協(xié)議
- 2025年上饒年終合同樣本
- 2025年中外著作權(quán)許可使用合同樣本
- 泰山英文簡介
- 公司組織知識清單范例
- 2023年部編高中語文選擇性必修上之海明威的冰山理論和電報(bào)體風(fēng)格
- WTE朗文英語 1B 單詞卡片
- 網(wǎng)咖成本預(yù)算明細(xì)表
- 2023年上半年重慶三峽融資擔(dān)保集團(tuán)股份限公司招聘6人上岸筆試歷年難、易錯點(diǎn)考題附帶參考答案與詳解
- 譯林版四年級下冊第一單元課件
- 標(biāo)志設(shè)計(jì) 課件
- 金屬常見的腐蝕形態(tài)及防護(hù)措施-課件
- (完整版)客戶拜訪方案
- 老年病科工作手冊
評論
0/150
提交評論