明人不說暗話,直接上百度網盤鏈接,輸入提取碼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 }