SisterRu

导航

 

 目标:实现一个可以计算加减乘除四种运算,可以识别处理'(',')','+','-','*','/','=',可以操作整数的计算器。

 步骤:(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 } 

 

 

 

posted on 2019-06-21 20:33  yiruzhao  阅读(15930)  评论(0编辑  收藏  举报