C++實現計算器


 目標:實現一個可以計算加減乘除四種運算,可以識別處理'(',')','+','-','*','/','=',可以操作整數的計算器。

 步驟:(1)將中綴表達式轉換成后綴表達式

    (2)計算后綴表達式

    (3)輸出結果

 准備工作:

 1.包含頭文件:

1 #include <iostream>
2 #include <stack>
3 #include <string>
4 
5 using namespace std;

 

 2.定義兩個棧

 

1 stack<char> opt;    // 操作符棧
2 stack<double> val;    // 操作數棧

 

 3.定義兩個常量表示在數字中的狀態

 

1 const int IN = 0;    // 在數字中
2 const int OUT = 1;    // 在數字外

 

 4.為操作符規定優先級,並判斷輸入的操作符是否合法

 

1 char opt_set[10] = "+-*/()=";

 

 

 1 /* 為每一個操作符返回一個數,數越大優先級越高 */
 2 
 3 int level(char theOpt){
 4     for(int i = 0; i < 7; i++){
 5         if(theOpt == opt_set[i])
 6             return i;
 7     }
 8     return -1;
 9 }
10 
11 /* 判斷輸入的操作符是否合法 */
12 
13 bool in_set(char theChar){
14     for(int i = 0; i < 7; i++){
15         if(theChar == opt_set[i])
16             return true;
17     }
18     return false;
19 }

 

 

 5.整理輸入,判斷是否有非法字符,用到in_set()函數

 1 /* 用於去除空格並檢查是否有非法字符 */
 2 bool del_space(string &theString){
 3     string res;
 4     for(int i = 0; i < theString.length(); i++){
 5         if(in_set(theString[i]) || isdigit(theString[i])){
 6             res += theString[i];
 7         }
 8         else if(theString[i] == ' ')
 9             ;
10         else{
11             cout << "表達式含有錯誤字符,請重新輸入。" << endl;
12             return false;
13         }
14     }
15     theString = res;
16     return true;
17 }
18
6.把數字轉換成字符串
20 21 string to_string(int theInt) 22 { 23 if(theInt == 0) 24 return string("0"); 25 bool neg = false; 26 if(theInt < 0) 27 { 28 neg = true; 29 theInt = -theInt; 30 } 31 string res; 32 while(theInt != 0) 33 { 34 char c = (theInt % 10) + '0'; 35 res = c + res; 36 theInt /= 10; 37 } 38 if(neg) 39 res = '-' + res; 40 return res; 41 }

 

 實現第一步:將中綴表達式轉化成后綴表達式

 

 1 /* 將中綴表達式轉換成后綴表達式 */
 2 bool change(string &from, string &to){
 3     int theInt = 0;        // 暫存數字
 4     int state = OUT;     // 初始狀態:在數字外
 5     char c;
 6     /*
 7     if(from[from.length() - 1] != '='){
 8         cout << "等於號語法有誤!" << endl;
 9         return false;
10     }
11     */
12     for(int i = 0; i < from.length(); i++){
13         c = from[i];
14         if(isdigit(c)){
15             theInt *= 10;
16             theInt += c - '0';
17             state = IN;    // 狀態:在數字內
18         }
19         else{
20             if(state == IN){        // 剛剛處理了數字
21                 to += to_string(theInt) + ' ';
22                 theInt = 0;
23             }
24             if(c == '='){
25                 /*
26                 if(i != from.length() - 1){
27                     cout << "等於號語法有誤!" << endl;
28                     return false;                    
29                 }
30                 */
31                 break;
32             }
33             else if(c == '(')
34                 opt.push(c);
35             else if(c == ')'){
36                 while(!opt.empty() && opt.top() != '('){
37                     to += opt.top();
38                     to += ' ';
39                     opt.pop();
40                 }
41                 /*
42                 if(opt.empty()){
43                     cout << "括號匹配有誤!" << endl;
44                     return false;
45                 }
46                 else
47                 */
48                     opt.pop();
49             }
50             else{
51                 while(true){
52                     if(opt.empty() || opt.top() == '(')
53                         opt.push(c);
54                     else if(level(c) > level(opt.top()))
55                         opt.push(c);
56                     else{
57                         to += opt.top();
58                         to += ' ';
59                         opt.pop();
60                         continue;
61                     }
62                     break;
63                 }
64             }
65             state = OUT;    // 狀態:在數字外
66         }
67     }
68     while(!opt.empty()){
69         /*
70         if(opt.top() == '('){
71             cout << "括號匹配有誤!" << endl;
72             return false;
73         }
74         */
75         to += opt.top();
76         to += ' ';
77         opt.pop();
78     }
79     return true;
80 } 

 

實現第二步:計算后綴表達式

 

 1 bool compute(string &theExp){
 2     int theInt = 0;        // 暫存數字
 3     int state = OUT;     // 初始狀態:在數字外
 4     char c;
 5     for(int i = 0; i < theExp.length(); i++){
 6         c = theExp[i];
 7         if(isdigit(c)){
 8             theInt *= 10;
 9             theInt += c - '0';
10             state = IN;    // 狀態:在數字內
11         }
12         else{
13             if(state == IN){        // 剛剛處理了數字
14                 val.push(theInt);
15                 theInt = 0;
16             }
17             double x, y;
18             if(c != ' '){
19                 /*
20                 if(val.empty()){
21                     cout << "操作數語法錯誤!" << endl;
22                     return false;
23                 }
24                 */
25                 x = val.top();
26                 val.pop();
27                 /*
28                 if(val.empty()){
29                     cout << "操作數語法錯誤!" << endl;
30                     return false;
31                 }
32                 */
33                 y = val.top();
34                 val.pop();
35                 switch(c){
36                     case '+':
37                         val.push(x + y);
38                         break;
39                     case '-':
40                         val.push(y - x);
41                         break;
42                     case '*':
43                         val.push(x * y);
44                         break;
45                     case '/':
46                         val.push(y / x);
47                         break;
48                     default:
49                         cout << "未知的錯誤!" << endl;
50                 }
51             }
52             state = OUT;
53         }
54     }
55     /*
56     if(val.size() != 1){
57         cout << "缺少操作符!" << endl;
58         return false;
59     }
60     */
61     return true;
62 }

 

實現第三步:測試,輸出結果

 

 1 int main()
 2 {
 3     cout << "請保證所有的操作數均為正整數,且不要輸入(+x)的形式。" << endl;
 4     cout << "若答案為小數,請按照四舍五入的規則保留小數點后三位。" << endl;
 5     while(true){
 6         // 清空流
 7         cin.clear();
 8         cin.sync();
 9         // 初始化操作:清空兩個棧
10         while(!opt.empty()){
11             opt.pop();
12         }
13         while(!val.empty()){
14             val.pop();
15         }
16         
17         // 輸入表達式
18         string init_exp;
19         cout << "請輸入以'='結尾的表達式,或輸入\"exit\"退出:";
20         getline(cin, init_exp);
21         
22         if(init_exp == string("exit")){
23             break;
24         }
25         
26         // 去除空格並檢查是否有非法字符
27         if(!del_space(init_exp))
28             continue;
29         
30         // 轉換為后綴表達式
31         string cng_exp;
32         cng_exp.clear();
33         if(!change(init_exp, cng_exp))
34             continue;
35         cout << "此表達式轉換為后綴表達式為:" << cng_exp << endl;
36         
37         // 計算后綴表達式
38         if(!compute(cng_exp))
39             continue;
40         
41         double stdans = val.top();
42         cout << "此表達式的運算結果為:" << stdans << endl;
43     }
44     return 0;
45 } 

 

 

 


免責聲明!

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



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