




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、1、 設計思想計算算術表達式可以用兩種方法實現(xiàn): 1.中綴轉(zhuǎn)后綴算法 此算法分兩步實現(xiàn):先將算術表達式轉(zhuǎn)換為后綴表達式,然后對后綴表達式進行計算。具體實現(xiàn)方法如下:(1) 中綴轉(zhuǎn)后綴 需要建一個操作符棧op和一個字符數(shù)組exp,op棧存放操作符,字符數(shù)組用來存放轉(zhuǎn)換以后的后綴表達式。首先,得到用戶輸入的中綴表達式,將其存入str數(shù)組中。對str數(shù)組逐個掃描,如果是數(shù)字或小數(shù)點,則直接存入exp數(shù)組中,當掃描完數(shù)值后,在后面加一個#作為分隔符。如果是操作符,并且棧為空直接入棧,如果棧不為空,與棧頂操作符比較優(yōu)先等級,若比棧頂優(yōu)先級高,入棧;如果比棧頂優(yōu)先級低或相等,出棧將其操作符存到exp數(shù)組中
2、,直到棧頂元素優(yōu)先等級低于掃描的操作符,則此操作符入棧;如果是左括號,直接入棧,如果是右括號,出棧存入exp數(shù)組,直到遇到左括號,左括號丟掉。然后繼續(xù)掃描下一個字符,直到遇到str中的結(jié)束符號0,掃描結(jié)束。結(jié)束后看op棧是否為空,若不為空,繼續(xù)出棧存入exp數(shù)組中,直到棧為空。到此在exp數(shù)組最后加結(jié)束字符0。我們就得到了后綴表達式。 (2) 后綴表達式計算此時需要一個數(shù)值棧od來存放數(shù)值。對exp數(shù)組進行逐個掃描,當遇到數(shù)字或小數(shù)點時,截取數(shù)值子串將其轉(zhuǎn)換成double類型的小數(shù),存入od棧中。當遇到操作符,從棧中取出兩個數(shù),進行計算后再放入棧中。繼續(xù)掃描,知道掃描結(jié)束,此時值棧中的數(shù)值就是
3、計算的結(jié)果,取出返回計算結(jié)果。2.兩個棧實現(xiàn)算法 此算法需要兩個棧,一個值棧od,一個操作符棧op。將用戶輸入的數(shù)學表達式存入str數(shù)組中,對其數(shù)組進行逐個掃描。當遇到數(shù)字或小數(shù)點,截取數(shù)值子串,將其轉(zhuǎn)換成double類型的數(shù)值存入od棧中;當遇到左括號,直接入op棧;遇到右括號,op棧出棧,再從值棧od中取出兩個數(shù)值,計算將其結(jié)果存入值棧中,一直進行此操作,直到操作符棧棧頂為左括號,將左括號丟掉。如果遇到操作符,若op棧為空,直接入棧;若棧不為空,與棧頂元素比較優(yōu)先等級,若比棧頂操作符優(yōu)先等級高,直接入op棧,如果低于或等于棧頂優(yōu)先等級,op棧出棧,再從值棧中取出兩個數(shù)值,計算將其結(jié)果存入值
4、棧中,一直進行此操作,直到棧頂優(yōu)先等級低于掃描的操作符等級,將此操作符入op棧。繼續(xù)掃描直到遇到str中的結(jié)束字符0,掃描結(jié)束。此時看操作符棧是否為空,若不為空,出棧,再從值棧中取出兩個數(shù)值進行計算,將其結(jié)果存入值棧,一直進行此操作,直到操作符棧為空。此時把值棧中的數(shù)值取出,即為所得的最終計算結(jié)果。二、算法流程圖第一種算法:中綴轉(zhuǎn)后綴算法其主函數(shù)流程圖為:圖1 主函數(shù)算法流程圖中綴轉(zhuǎn)后綴算法流程圖如下:圖2 中綴轉(zhuǎn)后綴算法流程圖計算后綴表達式流程圖如下: 圖3 后綴表達式計算流程圖第二種算法:兩個棧算法其主函數(shù)流程圖為:圖4 主函數(shù)算法流程圖直接計算數(shù)學表達式流程圖如下:圖5 直接計算表達式流
5、程圖三、源代碼下面給出的是用中綴轉(zhuǎn)后綴算法實現(xiàn)的程序的源代碼:#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define MAXSIZE 100 /定義宏,數(shù)組最大長度為100/函數(shù)實現(xiàn)中綴轉(zhuǎn)后綴,將存儲數(shù)學表達式的數(shù)組str傳參進來,exp存儲后綴表達式void trans(char str,char exp) struct char dataMAXSIZE;/用來存放操作符int top;/數(shù)組下標 op;/用結(jié)構(gòu)體創(chuàng)建操作符棧 char ch; i
6、nt i=0,j=0,tempi=0; op.top=-1;/給操作符棧初始化,令下標為-1 while(ch!='0') ch=stri; /取str數(shù)組的第i個元素賦值給ch if(ch>='0'&& ch<='9') | ch='.')/對數(shù)值操作 tempi=i;/若ch為數(shù)字或小數(shù)點,將其下標值賦給臨時下標tempi /依次向后掃描str數(shù)組,若一直為數(shù)字,跳入while循環(huán) while(ch>='0' && ch<= '9') |
7、ch = '.') tempi+; expj=ch;/將數(shù)字存入exp數(shù)組中 j+; ch=strtempi;/取str數(shù)組中下標為tempi的元素賦給ch expj='#'j+;/用#做分隔符,將數(shù)值分隔開 i=tempi;/跳出循環(huán),將此時的tempi賦給i,繼續(xù)向后掃描 /對操作符操作 else if(ch='+'|ch='-'|ch='*'|ch='/'|ch='%' | ch = '(' | ch = ')') int level(char
8、op);/聲明level函數(shù) if(ch='(')/如果為(,直接進棧 op.top+; op.dataop.top=ch;/進棧操作 else if(ch=')') /如果為),一直出棧直到遇到( while(level(op.dataop.top)!=-1)/若棧頂元素不為(,進入while循環(huán) expj=op.dataop.top;/操作符出棧,存入exp數(shù)組中 op.top-; j+; if(op.top=-1)break;/如果棧為空,跳出循環(huán) op.top-;/左括號pop出來 else if(op.top=-1)/如果棧為空,直接進棧 op.top
9、+; op.dataop.top=ch;/進棧操作 /如果所掃描的操作符優(yōu)先等級比棧頂元素高,直接進棧 else if(level(ch)>level(op.dataop.top) op.top+; op.dataop.top=ch;/進棧操作 else /如果所掃描的操作符優(yōu)先等級沒有棧頂元素高, /一直出棧直到比棧頂元素優(yōu)先級高 while(level(ch)<=level(op.dataop.top) expj=op.dataop.top;/出棧存入exp數(shù)組中 op.top-; j+; if(op.top=-1)break;/如果棧為空,跳出循環(huán) op.top+; op.d
10、ataop.top=ch;/比棧頂元素優(yōu)先級高,入棧 i+;/str下標加1,向后掃描 while(op.top!=-1)/掃描結(jié)束后如果操作符棧不為空,出棧直至為空 expj=op.dataop.top;/出棧存入exp數(shù)組中 op.top-; j+; expj='0'/賦0結(jié)束exp字符數(shù)組 int level(char op)/判斷操作符優(yōu)先等級if(op = '+' | op = '-')/若為+、-,等級為1return 1; else if(op = '*' | op = '/' | op = '
11、;%')return 2; /若為*、/、%,等級為2 else if(op = '(')return -1 ; /若為(,等級為-1 elsereturn -3; /其他等級為-3;double calvalue(double od1,double od2,char tempop)/計算switch(tempop)case '+': return od1 + od2; /計算加法case '-': return od1 - od2;/計算減法 case '*': return od1 * od2;/計算乘法 case &
12、#39;/': return od1 / od2;/計算除法case '%': return fmod(od1,od2);/求余return 0;double calculate(char exp)/計算后綴表達式struct /用結(jié)構(gòu)體創(chuàng)建值棧double dataMAXSIZE; /存儲數(shù)值int top;od; double d; /聲明d變量存儲數(shù)值double od1,od2; /存儲值棧依次pop出來的操作數(shù)char ch;char tempch20; /聲明臨時數(shù)組存儲子串int j=0,t;int length=strlen(exp);/計算exp數(shù)組的
13、長度od.top=-1; /初始化值棧,令下標為-1while(j<length)ch=expj;/提取exp中第j個元素if(ch!='+' && ch!='-' && ch!= '*' && ch!='/' && ch!='%')/如果為數(shù)字或小數(shù)點d=0;t=0;while(ch>='0' && ch<='9') |ch='.')tempcht=ch;t+;/依次存
14、放到臨時數(shù)組中j+;ch=expj;tempcht='0'/結(jié)束tempch數(shù)組d=atof(tempch);/將子串轉(zhuǎn)化成double類型的數(shù)od.top+;od.dataod.top=d;/入值棧else /若為操作符,從值棧中pop出兩個數(shù)計算 od2=od.dataod.top;od.top-;/先出棧的賦給od2od1=od.dataod.top; /后出棧的賦給od1od.dataod.top=calvalue(od1,od2,ch); /計算出結(jié)果后再入棧j+;return od.dataod.top;/將結(jié)束后值棧中的數(shù)pop出來,即為計算結(jié)果 main()ch
15、ar strMAXSIZE,expsMAXSIZE; /定義兩個數(shù)組printf("請輸入算術表達式:n");gets(str); /從控制臺輸入算數(shù)表達式 printf("表達式為: %sn",str);trans(str,exps); /調(diào)用trans函數(shù),得到后綴表達式printf("后綴表達式:%sn",exps);printf("結(jié)果為:%lfn",calculate(exps);/調(diào)用calculate函數(shù),計算結(jié)果下面給出的是用兩個棧算法實現(xiàn)的程序的源代碼:#include<stdio.h>
16、;#include<string.h>#include<math.h>#include<stdlib.h>#define MAXSIZE 100 /定義宏,數(shù)組最大長度為100double calculate(char str)struct /用結(jié)構(gòu)體創(chuàng)建操作符棧 char dataMAXSIZE;/用來存放操作符int top;op; struct /用結(jié)構(gòu)體創(chuàng)建值棧 double dataMAXSIZE;/用來存放操作數(shù)int top;od; char ch;char tempch20;/聲明臨時數(shù)組存儲子串int j=0,t;double d;doub
17、le od1,od2;/存儲值棧依次pop出來的操作數(shù)char tempop;int length=strlen(str);/計算str數(shù)組的長度op.top=-1;/初始化操作符棧,令下標為-1od.top=-1;/初始化值棧while(j<length) ch=strj;if(ch>='0' && ch<='9') |ch='.')/若為數(shù)值或小數(shù)點d=0;t=0;while(ch>='0' && ch<='9') |ch='.')/
18、截取子串tempcht=ch;t+;/賦值給臨時數(shù)組 j+;ch=strj;tempcht='0'd=atof(tempch);/將子串轉(zhuǎn)化成double類型的數(shù)od.top+;od.dataod.top=d;/入值棧/對操作符操作else if(ch='+'|ch='-'|ch='*'|ch='/'|ch='%' | ch = '(' | ch = ')') if(ch='(')/如果為(,直接進棧op.top+;op.dataop.top=ch;/
19、進棧操作else if(ch=')')/如果為),一直出棧直到遇到( int level(char op);/聲明level函數(shù)while(level(op.dataop.top)!=-1)/若棧頂元素不為(,進入while循環(huán)/聲明calvalue函數(shù)double calvalue(double od1,double od2,char tempop);od2=od.dataod.top;od.top-;od1=od.dataod.top;tempop=op.dataop.top;op.top-;od.dataod.top=calvalue(od1,od2,tempop);/計
20、算出結(jié)果后入值棧if(op.top=-1)break;/如果操作符棧為空,跳出循環(huán)op.top-;/左括號pop出來else if(op.top=-1)/如果棧為空,直接進棧op.top+;op.dataop.top=ch;/進棧操作/如果所掃描的操作符優(yōu)先等級比棧頂元素高,直接進棧else if(level(ch)>level(op.dataop.top)op.top+;op.dataop.top=ch;/進棧操作else /如果所掃描的操作符優(yōu)先等級沒有棧頂元素高,/一直出棧直到比棧頂元素優(yōu)先級高while(level(ch)<=level(op.dataop.top)od2=
21、od.dataod.top;od.top-;od1=od.dataod.top;tempop=op.dataop.top;op.top-;od.dataod.top=calvalue(od1,od2,tempop);/計算結(jié)果后入值棧if(op.top=-1)break;/如果棧為空,跳出循環(huán)op.top+;op.dataop.top=ch;/比棧頂元素優(yōu)先級高,入操作符棧j+;/str下標加1,向后掃描 while(op.top!=-1)/掃描結(jié)束后如果操作符棧不為空,出棧直至為空 od2=od.dataod.top;od.top-; od1=od.dataod.top; tempop=op
22、.dataop.top;op.top-; od.dataod.top=calvalue(od1,od2,tempop);/計算結(jié)果后入值棧 return od.dataod.top;/將結(jié)束后值棧中的數(shù)pop出來,即為計算結(jié)果int level(char op)/判斷操作符優(yōu)先等級if(op = '+' | op = '-')/若為+、-,等級為1return 1; else if(op = '*' | op = '/' | op = '%')return 2; /若為*、/、%,等級為2 else if(op =
23、 '(')return -1 ; /若為(,等級為-1 elsereturn -3; /其他等級為-3;double calvalue(double od1,double od2,char tempop)/計算switch(tempop)case '+': return od1 + od2;/計算加法case '-': return od1 - od2;/計算減法 case '*': return od1 * od2;/計算乘法 case '/': return od1 / od2;/計算除法case '%
24、': return fmod(od1,od2);/求余return 0;void main()char strMAXSIZE;/定義str數(shù)組存放數(shù)學表達式printf("輸入算術表達式:n");gets(str); /從控制臺輸入算數(shù)表達式printf("結(jié)果是:%lfn",calculate(str);/調(diào)用calculate函數(shù),計算結(jié)果四、運行結(jié)果圖6 中綴轉(zhuǎn)后綴算法運行結(jié)果圖7 兩個棧算法運行結(jié)果5、 遇到的問題及解決編程的前期工作很重要,需要明確的理清思路,而編寫運行的過程中更是會出現(xiàn)很多問題,有因粗心造成的拼寫錯誤,有語法錯誤,也有
25、邏輯錯誤。在整個編程過程我主要遇到了如下幾個大的問題,其內(nèi)容與解決方法如下所列:l 將字符表示的數(shù)字轉(zhuǎn)化為浮點數(shù)Java中有現(xiàn)成的截取子串的方法可以用,而我的c語言基礎比較薄弱,所學知 識也不全面。剛開始的思路是先將出現(xiàn)數(shù)字的子串計數(shù),得到一共有多少個數(shù)字,然后再從子串開始處掃描,依次乘以它的位權,在百位就乘以10的2次方,依次類推。經(jīng)過很長時間的思考,終于寫出了此解決方法,可是卻忽略了小數(shù)點的存在。又開始用此方法試圖解決存在小數(shù)點的問題,想了好久也沒有解決方法。無奈之下求助于網(wǎng)絡,看有沒有什么更好的解決辦法,一經(jīng)查詢知道了stdlib.h庫中有atof的函數(shù)可以將字符串類型的數(shù)字轉(zhuǎn)換為浮點型。于是我用一個while循環(huán)將
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)殖肉牛項目可行性報告
- 互聯(lián)網(wǎng)立項報告
- 母嬰護理中級復習試題含答案
- 護理-婦產(chǎn)科護理學練習卷含答案
- 醫(yī)療機構(gòu)信息管理系統(tǒng)應急預案
- 建筑結(jié)構(gòu)穩(wěn)定性分析報告書
- 主管護師內(nèi)科護理復習試題及答案
- 鄉(xiāng)村衛(wèi)生保健推廣方案
- 針對網(wǎng)絡安全問題的解決方案與實施計劃
- 用戶體驗優(yōu)化針對不同地區(qū)
- 產(chǎn)時會陰消毒課件
- 第一單元 我們的守護者 (同步練習)部編版道德與法治六年級上冊
- 河南省商丘市部分校2024~2025學年度高二上學期期末聯(lián)考語文試題含答案
- 2025年高考時事政治考點總結(jié)
- 2025年山西省運城市平陸縣部分學校中考一模道德與法治試題(原卷版+解析版)
- 第十單元課題2 常見的酸和堿第1課時-2024-2025學年九年級化學人教版下冊
- 小學生數(shù)據(jù)分析課件
- 2025年皖北衛(wèi)生職業(yè)學院單招職業(yè)適應性測試題庫附答案
- 2025年山東國電投萊陽核能有限公司校園招聘筆試參考題庫附帶答案詳解
- 中小學生開學第一課主題班會-以哪吒之魔童降世為榜樣
- 2024年中國疾控中心信息中心招聘考試真題
評論
0/150
提交評論