




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
用到的是算符優(yōu)先法的思想,現(xiàn)摘自嚴(yán)蔚敏的數(shù)據(jù)結(jié)構(gòu)(C語(yǔ)言版)的3.2.5章來(lái)詳細(xì)說(shuō)明算符優(yōu)先法的思想:
(摘抄結(jié)束)我給出的計(jì)算器功能有:支持歐拉數(shù)e,支持圓周率pi,支持運(yùn)算符=,-,*,/,求冪符號(hào)^,階乘!,正弦sin,余弦cos,正切tan,以10為底的對(duì)數(shù)函數(shù)lg,以歐拉數(shù)為底的對(duì)數(shù)函數(shù)ln,優(yōu)先級(jí)表為:(!表示不合法)#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<string.h>#include<math.h>//引用請(qǐng)注明出處:://hi.baidu/liangxiaowen1989/blog/item/af972310f7119670ca80c413.html#defineMAX_TOKEN_LEN100//標(biāo)記最大長(zhǎng)度#defineEXPR_INCREMENT20//表達(dá)式長(zhǎng)度的增量typedefstruct{ doubleopnd;//操作數(shù) charoptr[11];//運(yùn)算符 intflag;//若為1,則為單目運(yùn)算符,2則是雙目運(yùn)算符}SElemType;//棧元素類型typedefstructSNode{//棧 SElemTypedate; structSNode*next;}SNode,*Stack;struct{//用來(lái)存儲(chǔ)一個(gè)操作數(shù)或運(yùn)算符 charstr[MAX_TOKEN_LEN]; inttype;//類型,若為0,則為操作數(shù),若為1則為運(yùn)算符}token;struct{//expression,用來(lái)存儲(chǔ)表達(dá)式 char*str; intcur;//標(biāo)記讀取expr的當(dāng)前位置}expr;StackOPND,OPTR;//操作數(shù)棧operand,運(yùn)算符棧operatorintexpr_size;//表達(dá)式長(zhǎng)度voidInitStack(Stack*S){//初始化棧 *S=(Stack)malloc(sizeof(SNode)); if(!(*S)){ printf("動(dòng)態(tài)申請(qǐng)內(nèi)存失敗!\n"); exit(0); }//if (*S)->next=NULL;}//InitStackvoidDestroyStack(Stack*S){//銷毀棧 SNode*p; while(p=*S){ *S=p->next; free(p); }//while}//DestroyStackvoidPush(StackS,SElemTypee){//入棧 SNode*p; p=(SNode*)malloc(sizeof(SNode)); if(!p){ printf("動(dòng)態(tài)申請(qǐng)內(nèi)存失敗!\n");exit(0); }//if strcpy(p->date.optr,e.optr); p->date.opnd=e.opnd; p->date.flag=e.flag; p->next=S->next; S->next=p;}//PushvoidPop(StackS,SElemType*e){//出棧 SNode*p; p=S->next; if(!p){ printf("棧為空,不能出棧!\n"); exit(0); }//if S->next=p->next; strcpy(e->optr,p->date.optr); e->opnd=p->date.opnd; e->flag=p->date.flag; free(p);}//Popvoidget_expr(){//獲取expr字符串 char*p; intsize; expr.cur=0; expr_size=100; expr.str=(char*)malloc(expr_size*sizeof(char)); if(!expr.str){ printf("內(nèi)存分配失敗!\n"); exit(0); }//if size=0; p=expr.str; while((*p=getchar())!='\n'){ if(*p!='.huisheliren'){ if((*p>='A')&&(*p<='Z')){ *p=*p+32;//將大寫轉(zhuǎn)換成小寫 }//if p++; size++; if(size==expr_size-1){//此時(shí)expr.str已滿,將其擴(kuò)大 expr_size+=EXPR_INCREMENT; expr.str=(char*)realloc(expr.str,expr_size*sizeof(char)); if(!expr.str){ printf("內(nèi)存分配失敗!\n"); exit(0); }//if p=&expr.str[size];//realloc后需重新指定p }//if }//if }//while *p++='#'; *p='\0';}//get_exprintIsOpnd(charch){//判斷ch是否是操作數(shù)的一部分 if((ch>='0')&&(ch<='9')||(ch=='.')){ return1; }//if if((ch=='-')||(ch=='+')){//如若+-前面是'#'或'(',則為正負(fù)號(hào) if((expr.cur==0)||(expr.str[expr.cur-1]=='(')){ return1; }//if }//if return0;}//IsOpndvoidgettoken(){//獲取一個(gè)標(biāo)記 char*p=token.str; *p=expr.str[expr.cur]; if(IsOpnd(*p)){ while(IsOpnd(*++p=expr.str[++expr.cur]));//注意是分號(hào)結(jié)尾 *p='\0'; token.type=0;//將標(biāo)記類型設(shè)定為操作數(shù) return; }//if if((*p>='a')&&(*p<='z')){//接收sin,tan,ln之類的函數(shù)運(yùn)算符或操作數(shù) while((expr.str[expr.cur+1]>='a')&&(expr.str[expr.cur+1]<='z')){ *++p=expr.str[++expr.cur]; }//while }//if ++expr.cur; *++p='\0'; if(!strcmp(token.str,"e")){//e為歐拉數(shù),既自然對(duì)數(shù)的底數(shù) sprintf(token.str,"%.16g",exp(1));//springf是庫(kù)函數(shù),功能是將顯示在屏幕上的內(nèi)容儲(chǔ)存在字符串中 token.type=0; return; }//if if(!strcmp(token.str,"pi")){//pi為圓周率 //sprintf(token.str,"%.16g",exp(1));//springf是庫(kù)函數(shù),功能是將顯示在屏幕上的內(nèi)容儲(chǔ)存在字符串中 strcpy(token.str,"3.1415926535897932"); token.type=0; return; }//if token.type=1;//將標(biāo)記類型設(shè)定為運(yùn)算符}//gettokencharPrecede(SElemType*optr1,SElemType*optr2){//返回優(yōu)先關(guān)系 char*str1,*str2; str1=optr1->optr; str2=optr2->optr; if(!strcmp(str1,"ln")||!strcmp(str1,"lg")||!strcmp(str1,"sin")||!strcmp(str1,"cos")||!strcmp(str1,"tan")){ optr1->flag=1;//這些均為單目運(yùn)算符 return(!strcmp(str2,"(")||!strcmp(str2,"^")||!strcmp(str2,"!"))?'<':'>'; }//if if(!strcmp(str1,"!")){ optr1->flag=1; return'>'; }//if optr1->flag=2; switch(str1[0]){ case'+':case'-':return(!strcmp(str2,"+")||!strcmp(str2,"-")||!strcmp(str2,")")||!strcmp(str2,"#"))?'>':'<'; case'*':case'/':return(!strcmp(str2,"+")||!strcmp(str2,"-")||!strcmp(str2,"*")|| !strcmp(str2,"/")||!strcmp(str2,")")||!strcmp(str2,"#"))?'>':'<'; case'(':return!strcmp(str2,")")?'=':'<'; case')':return'>'; case'^':return(!strcmp(str2,"(")||!strcmp(str2,"!")||!strcmp(str2,"^"))?'<':'>'; case'#':return!strcmp(str2,"#")?'=':'<'; }//switch}//Precedelongfactorial(longn){//階乘 return(n<=1)?1:n*factorial(n-1);}//factorialSElemTypeOperate(SElemTypeopnd1,SElemTypeoptr,SElemTypeopnd2){//計(jì)算 SElemTypetemp; if(optr.flag==1){ if(!strcmp(optr.optr,"!"))temp.opnd=factorial((long)opnd2.opnd); elseif(!strcmp(optr.optr,"lg"))temp.opnd=log10(opnd2.opnd); elseif(!strcmp(optr.optr,"ln"))temp.opnd=log(opnd2.opnd); elseif(!strcmp(optr.optr,"sin"))temp.opnd=sin(opnd2.opnd); elseif(!strcmp(optr.optr,"cos"))temp.opnd=cos(opnd2.opnd); elseif(!strcmp(optr.optr,"tan"))temp.opnd=tan(opnd2.opnd); returntemp; }//if switch(optr.optr[0]){ case'+':temp.opnd=opnd1.opnd+opnd2.opnd;break; case'-':temp.opnd=opnd1.opnd-opnd2.opnd;break; case'*':temp.opnd=opnd1.opnd*opnd2.opnd;break; case'/':temp.opnd=opnd1.opnd/opnd2.opnd;break; case'^':temp.opnd=pow(opnd1.opnd,opnd2.opnd); }//switch returntemp;}//Operateintmain(){ SElemTypeoptr,opnd1,opnd2; printf("\n歡迎使用簡(jiǎn)易科學(xué)計(jì)算器!\n"); printf("歐拉數(shù)為e,圓周率為pi,退出則輸入quit!\n"); printf("優(yōu)先級(jí):括號(hào)高于'!'高于'^'高于lg,ln,sin,cos,tan高于*,/高于+,-\n"); printf("請(qǐng)輸入計(jì)算表達(dá)式:\n\n"); while(1){ get_expr(); if(!strcmp(expr.str,"quit#")){ return0; }//if InitStack(&OPTR); InitStack(&OPND); strcpy(optr.optr,"#"); Push(OPTR,optr); gettoken();//從expr.str中獲取一個(gè)標(biāo)記(操作數(shù)或運(yùn)算符) while(strcmp(token.str,"#")||strcmp(OPTR->next->date.optr,"#")){ if(token.type){//說(shuō)明token存儲(chǔ)的是運(yùn)算符 strcpy(optr.optr,token.str); switch(Precede(&(OPTR->next->date),&optr)){ case'<'://棧頂元素優(yōu)先權(quán)低 strcpy(optr.optr,token.str); Push(OPTR,optr); gettoken(); break; case'='://脫括號(hào)并接收下一字符 Pop(OPTR,&optr); gettoken(); break; case'>'://退棧并將運(yùn)算結(jié)果入棧 Pop(OPTR,&optr); Pop(OPND,&opnd2); if(optr.flag==2){//是雙目運(yùn)算符才需另一個(gè)操作符 Pop(OPND,&opnd1); }//if Push(OPND,Operate(opnd1,optr,opnd2)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年生豬出欄面試試題及答案
- 基坑沙土置換施工方案
- grc輕質(zhì)隔墻施工方案
- 5年級(jí)說(shuō)明文例文
- cba實(shí)驗(yàn)環(huán)境要求
- 單面墻模板施工方案
- 瀝青路面灌縫施工方案
- 余江標(biāo)識(shí)標(biāo)牌施工方案
- 石籠擋墻施工方案
- 2025年新疆塔城地區(qū)單招職業(yè)傾向性測(cè)試題庫(kù)必考題
- 2024行政執(zhí)法人員考試題庫(kù)及答案
- 國(guó)家中醫(yī)藥管理局發(fā)布的406種中醫(yī)優(yōu)勢(shì)病種診療方案和臨床路徑目錄
- 2024年水利部長(zhǎng)江水利委員會(huì)直屬事業(yè)單位招聘歷年【重點(diǎn)基礎(chǔ)提升】模擬試題(共500題)附帶答案詳解
- 衛(wèi)健委監(jiān)管醫(yī)院合同簽訂流程規(guī)定
- DL-T5704-2014火力發(fā)電廠熱力設(shè)備及管道保溫防腐施工質(zhì)量驗(yàn)收規(guī)程
- CBZ125-1998-潛艇船體結(jié)構(gòu)焊接質(zhì)量檢驗(yàn)規(guī)則
- 2024年河南省信陽(yáng)市浉河區(qū)二模語(yǔ)文試卷
- 代理商區(qū)域保護(hù)協(xié)議書(shū)范本
- 2024年包頭鋼鐵職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)適應(yīng)性測(cè)試題庫(kù)及答案解析
- 英語(yǔ)定位紙模板
- 中外政治思想史-形成性測(cè)試四-國(guó)開(kāi)(HB)-參考資料
評(píng)論
0/150
提交評(píng)論