數據結構課程設計四則運算表達式求值(C語言版)


  明人不說暗話,直接上百度網盤鏈接,輸入提取碼z3fy即可下載

    文件中包含程序,程序運行文件,設計報告和測試樣例,應有盡有,歡迎小伙伴們在中下載使用。

    本課程設計為四則運算表達式求值,用於帶小括號的一定范圍內正負數的四則運算標准(中綴)表達式的求值。
注意事項:
    1、請保證輸入的四則表達式的合法性。輸入的中綴表達式中只能含有英文符號“+”、“-”、“*”、“/”、“(”、“)”、“=”、數字“0”到“9”以及小數點“.”,輸入“=”表示輸入結束。例如9+(3-1)*3.567+10/2=,特別是請勿輸入多余空格和中文左右括號。
    2、輸入的中綴表達式默認限定長度是1001,可根據具體情況調整字符串數組的長度。
    3、請保證輸入的操作數在double數據類型范圍內,單個數字有效數字長度不可超過15位。本課程設計中操作數是C語言中的雙精度浮點數類型。
    4、本課程設計中的運算數可以是負數,另外如果是正數可直接省略“+”號(也可帶“+”號)。

 下面的程序正常運行需要在上面的百度網盤中下載相應文件,否則無法正常使用哦。

  1 /*本程序為四則運算表達式求值系統,用於計算帶小括號的四則運算表達式求值。
  2 具體算法:
  3     先將字符串處理成操作單元(操作數或操作符),再利用棧根據四則運算
  4 的運算法則進行計算,最后得出結果。*/ 
  5 
  6 #include<stdio.h>
  7 #include<ctype.h>
  8 #include<stdlib.h>
  9 #include<string.h>
 10 #include<stdlib.h>
 11 #include<ctype.h>
 12 
 13 const int Expmax_length = 1001;//表達式最大長度,可根據適當情況調整 
 14 struct Ope_unit 
 15 {//定義操作單元 
 16     int    flag;//=1表示是操作數 =0表示是操作符 -1表示符號單元 
 17     char   oper;//操作符 
 18     double real;//操作數,為雙精度浮點數 
 19 };
 20 
 21 void Display();//菜單
 22 void Instru(); //使用說明 
 23 int Check(char Exp_arry[]);
 24 void Evalua(); //先調用Conver操作單元化,再調用Calculate函數計算結果並輸出 
 25 int  Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//將字符串處理成操作單元 
 26 int  Isoper(char ch);//判斷合法字符(+ - * / ( ) =)
 27 int  Ope_Compar(char ope1,char ope2);//操作符運算優先級比較 
 28 double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//用棧計算表達式結果 
 29 double Four_arithm(double x,double y,char oper);//四則運算 
 30 
 31 int main()
 32 {
 33     int select;
 34     while(1)
 35     {
 36         Display();
 37         printf("請輸入欲執行功能對應的數字:"); 
 38         scanf("%d",&select);
 39         printf("\n");
 40         switch(select)
 41         {
 42             case   1: Evalua(); break;
 43             case   2: Instru(); break;
 44             case   0: return 0; 
 45             default : printf("無該數字對應的功能,請重新輸入\n"); 
 46                       system("pause");
 47         }
 48     }
 49     return 0;
 50 }
 51 
 52 int Check(char Exp_arry[])
 53 {//檢查是否有非法字符,返回1表示不合法,0表示合法 
 54     int Explength=strlen(Exp_arry),i;
 55     for(i=0;i<Explength;i++)
 56     {
 57         if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))
 58         return 1;
 59         if(isdigit(Exp_arry[i]))
 60         {
 61             int Dig_number=0,Cur_positoin=i+1;
 62             while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')
 63             {
 64                 Dig_number++;
 65                 Cur_positoin++;
 66             }
 67             if(Dig_number >= 16)//最多能夠計算15位有效數字 
 68             return 1;
 69         }
 70     }
 71     return 0;
 72 }
 73 
 74 void Evalua()
 75 {//先調用Conver函數將字符串操作單元化,再調用Calculate函數計算結果並輸出 
 76     char Exp_arry[Expmax_length];
 77     int flag=0;//假設剛開始不合法,1表達式合法,0不合法 
 78     struct Ope_unit Opeunit_arry[Expmax_length];
 79     
 80     getchar();//吃掉一個換行符 
 81     printf("請輸入四則運算表達式,以=結尾:\n"); 
 82     gets(Exp_arry);
 83     flag=Check(Exp_arry);
 84     if(flag) 
 85     printf("該表達式不合法!\n");
 86     else
 87     {
 88         int Opeunit_count = Conver(Opeunit_arry,Exp_arry);
 89         double        ans = Calculate(Opeunit_arry,Opeunit_count,flag);
 90         if(flag)
 91         {
 92             printf("計算結果為:\n");
 93             printf("%s%lf\n",Exp_arry,ans);
 94         }
 95         else
 96         printf("該表達式不合法!\n");
 97     }
 98     system("pause"); 
 99 }
100 
101 int  Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])
102 {//將字符串操作單元化 
103     int Explength=strlen(Exp_arry);
104     int i,Opeunit_count=0;
105     for(i=0;i<Explength;i++)
106     {    
107         if(Isoper(Exp_arry[i]))//是操作符 
108         {
109             Opeunit_arry[Opeunit_count].flag=0;
110             Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];
111         }
112         else//是操作數 
113         {
114             Opeunit_arry[Opeunit_count].flag=1;
115             char temp[Expmax_length];
116             int k=0;
117             for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++) 
118             {
119                 temp[k++]=Exp_arry[i];
120             }
121             i--;
122             temp[k]='\0';
123             Opeunit_arry[Opeunit_count].real=atof(temp);//將字符轉化為浮點數
124             
125             //負數 
126             if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0 
127             && Opeunit_arry[Opeunit_count-1].oper=='-')
128             {        
129                 Opeunit_arry[Opeunit_count-1].flag = -1; 
130                 Opeunit_arry[Opeunit_count].real  *= -1;
131             }// -9 
132             if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0 
133             && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 
134             && Opeunit_arry[Opeunit_count-2].oper !=')')
135             {        
136                 Opeunit_arry[Opeunit_count-1].flag = -1; 
137                 Opeunit_arry[Opeunit_count].real  *= -1;
138             }// )-9
139             
140             //正數 
141             if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0 
142             && Opeunit_arry[Opeunit_count-1].oper=='+')
143             {        
144                 Opeunit_arry[Opeunit_count-1].flag = -1; 
145             }// +9 
146             if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0 
147             && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0 
148             && Opeunit_arry[Opeunit_count-2].oper !=')')
149             {        
150                 Opeunit_arry[Opeunit_count-1].flag = -1; 
151             }// )+9
152             Opeunit_count++;
153         }
154     }
155     /*for(i=0;i<Opeunit_count;i++)
156     {//查看各操作單元是否正確,1是操作數,0是操作符 
157         if(Opeunit_arry[i].flag == 1)
158         printf("該單元是操作數為:%lf\n",Opeunit_arry[i].real);
159         else if(Opeunit_arry[i].flag == 0)
160         printf("該單元是操作符為:%c\n",Opeunit_arry[i].oper);
161         else
162         printf("該單元是負號符為:%c\n",Opeunit_arry[i].oper);
163     }*/
164     return Opeunit_count;
165 } 
166 
167 double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)
168 {//根據運算規則,利用棧進行計算 
169     int i,dS_pointer=0,oS_pointer=0;//dS_pointer為操作數棧頂指示器,oS_pointer為操作符棧頂指示器 
170     double Dig_stack[Expmax_length];//操作數棧(順序存儲結構) 
171     char   Ope_stack[Expmax_length];//操作符棧 
172     
173     for(i=0;i<Opeunit_count-1;i++)
174     {
175         if( Opeunit_arry[i].flag != -1 )
176         {
177             if(Opeunit_arry[i].flag)//是操作數 
178             {
179                 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//入操作數棧 
180                 //printf("%lf\n",Digit[dS_pointer-1]);
181             }
182             else//是操作符 + - * / ( ) 
183             {
184                 //操作符棧為空或者左括號 入棧
185                 if(oS_pointer==0 || Opeunit_arry[i].oper=='(')  
186                 {
187                     Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
188                     //printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);
189                 }
190                 else
191                 {
192                     if(Opeunit_arry[i].oper==')')//是右括號將運算符一直出棧,直到遇見左括號 
193                     {
194                         oS_pointer--;//指向棧頂 
195                         dS_pointer--;//指向棧頂 
196                         while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)
197                         {
198                             Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer],
199                             Ope_stack[oS_pointer--]);//oS_pointer--為操作符出棧 
200                             
201                             dS_pointer--;//前一個操作數出棧 
202                             //printf("操作數棧頂元素等於%lf\n",Digit[dS_pointer]);
203                         }
204                         oS_pointer--;//左括號出棧
205                          
206                         oS_pointer++;//恢復指向棧頂之上 
207                         dS_pointer++;
208                     }
209                     else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和棧頂元素比較 
210                      {
211                          Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
212                          //printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);
213                     } 
214                      else//運算符出棧,再將該操作符入棧 
215                      {
216                          oS_pointer--;//指向棧頂 
217                          dS_pointer--;//指向棧頂
218                         while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1)
219                         {//當前操作符比棧頂操作符優先級高 
220                             Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer],
221                             Ope_stack[oS_pointer--]);
222                             dS_pointer--;
223                             //printf("操作數棧頂元素等於%lf\n",Digit[dS_pointer]);
224                         }
225                         oS_pointer++;//恢復指向棧頂之上  
226                         dS_pointer++;
227                         Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
228                     }
229                 } 
230             }    
231         }
232     }
233     /*for(i=0;i<oS_pointer;i++)
234         printf("操作符棧%oS_pointer\Ope_u_count",Operator[i]);
235     for(i=0;i<dS_pointer;i++)
236         printf("操作數棧%lf\n",Digit[i]);*/
237     oS_pointer--;//指向棧頂元素 
238     dS_pointer--;//指向棧頂元素 
239     while(oS_pointer != -1)
240     {
241         Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer],
242         Ope_stack[oS_pointer--]);//oS_pointer--為操作符出棧 
243         dS_pointer--;//前一個操作數出棧 
244         //printf("操作數棧頂元素為%lf\Ope_u_count",Digit[dS_pointer]);
245     }
246     //printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);
247     if(oS_pointer==-1 && dS_pointer==0)
248         flag=1;//為1表示表達式合法 
249     return Dig_stack[0];
250 }
251 
252 int  Ope_Compar(char ope1,char ope2)
253 {//操作符運算優先級比較
254     char list[]={"(+-*/"};
255     int map[5][5]={//先行后列,行比列的運算級優先級低為0,高為1 
256     //        ( + - * /    
257     /*  (  */ 1,0,0,0,0,
258     /*  +  */ 1,0,0,0,0,
259     /*  -  */ 1,0,0,0,0,
260     /*  *  */ 1,1,1,0,0,
261     /*  /  */ 1,1,1,0,0 };
262     int i,j;
263     for(i=0;i<5;i++) 
264         if(ope1==list[i]) break;
265     for(j=0;j<5;j++) 
266         if(ope2==list[j]) break;
267     return map[i][j];
268 }
269 
270 double Four_arithm(double x,double y,char oper)
271 {//四則運算 
272     switch(oper)//保證不含其它運算符 
273     {
274         case '+': return x+y;
275         case '-': return x-y;
276         case '*': return x*y;
277         case '/': return x/y;//y不能為0 
278         default : return 0; 
279     }
280 }
281 
282 int  Isoper(char ch)
283 {//判斷合法字符  + - * / ( ) =
284     if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=') 
285         return 1;
286     return 0;
287 }
288 
289 void Display()
290 {//打印菜單 
291     system("cls");
292     printf("/******************************************************************************/\n");
293     printf("\t\t       歡迎使用本四則運算表達式求值系統\n");
294     printf("\n\t說明:建議請您先閱讀使用說明,再輸入相應的數字進行操作,謝謝配合!\n"); 
295     printf("\n\t\t1 四則運算表達式求值\n"); 
296     printf("\n\t\t2 使用說明\n");
297     printf("\n\t\t0 退出\n"); 
298     printf("/******************************************************************************/\n");
299 }
300 
301 void Instru()
302 {//打印使用說明 
303     FILE *fp;
304     char ch;
305     if( ( fp=fopen("使用說明.txt","r") ) == NULL)
306     {
307         printf("文件打開失敗!\n");
308         exit(0); 
309     } 
310     for(; (ch = fgetc(fp)) != EOF; )
311         putchar(ch);
312     fclose(fp);
313     printf("\n");
314     system("pause"); 
315 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM