标签:
1 /**
2 *注:1.有一个bug(以及未知什么bug) 我已知的是: (a@b)(ps:@为运算符),这种带括号的表达式不能单独的出现,否则异常退出,,但是只要(a@b)@n
3
4 带括号的表达式出现任意+,-,*,/的运算都能进行正常运算(前面 n@(a@b)也不可以)。。。不知道为什么()表达式后面没有操作时会异常退出。
5 *不知道如何解决。希望感兴趣的人帮帮忙!
6
7 //--------------------------------------------
8 *一般的数式计算(允许括号的)需要通过栈来实现,但是其实对一些新手(我还没学数据结构)来说,用递归其实也是能很好的实现的。而且也很易于理解。
9 *主要思路是-判断是有括号,无括号情况,有乘除和无乘除。有乘除时将乘除先算,算出来的值取代乘除的算式。
10 *将括号中的数先算,将算出来的式子的值(括号中也会进行判断是否有无括号,有无乘除)将算出来的数取代原来的算式,然后递归.
11 *最后的结束条件(判断其中运算符的数量): 只要算一个单一运算符的式子,因为在递归中所有的复杂的式子都被替换成了值。
12 */
13
14 #include<iostream>
15 #include<cctype>
16 #include<vector>
17 #include<cstdlib>
18 #include<cstring>
19 #include<string>
20
21 #define Jia 100001
22 #define Jian 100002
23 #define Chen 100003
24 #define Chu 100004
25 #define Qian 100005
26 #define Hou 100006
27
28 using namespace std;
29
30 void Exchange(vector<double>& v, string s); //将字符串转换成double型数
31 double Calculate_Single(vector<double> v); //进行数式计算
32 double Count(double a, double b, double c); //计算一组算式
33 double integer(char c,double &rin); // 将连续数字字符串转换为整数
34
35 double integer(char c,double &rin) // 将连续数字字符串转换为整数
36 {
37 rin = rin*10 + (c-‘0‘);
38 return rin;
39 }
40
41 void Exchange(vector<double>& v, string s)
42 {
43 char *p = &s[0];
44 double re;
45 while (*p) {
46 re = 0;
47 for ( ; *p; ++p) {
48 if (isdigit(*p)) //如果是数字字符
49 integer(*p, re); //转换成整数
50 else{
51 if (*p == ‘(‘) { v.push_back(Qian); p++;}
52 break;
53 }
54 }
55 if (re)
56 v.push_back(re);
57 if (*p == ‘\0‘)
58 break;
59 p--;
60 while (*p++) {
61 if (*p == ‘+‘) { v.push_back(Jia); continue; }
62 if (*p == ‘-‘) { v.push_back(Jian); continue; }
63 if (*p == ‘*‘) { v.push_back(Chen); continue; }
64 if (*p == ‘/‘) { v.push_back(Chu); continue; }
65 if (*p == ‘(‘) { v.push_back(Qian); continue; }
66 if (*p == ‘)‘) { v.push_back(Hou); continue; }
67 if (isdigit(*p))
68 break;
69 }
70 }
71 // cout << re << endl; //debug
72 }
73
74 double Count(double a, double b, double c) {
75 if (c == Jia) return a + b;
76 if (c == Jian) return a - b;
77 if (c == Chen) return a * b;
78 if (c == Chu) return a / b;
79 cerr << "运算出错,运算符不为+、-、*、/ !\n";
80 exit(1);
81 }
82
83 //思路:递归--将乘除,括号这些地方的算式算成值,替换到只有加减的式子中去,最后这个只要算一个只有加减的式子即可
84 double Calculate_Single(vector<double> v) //进行数式计算带括号--用递归实现
85 {
86 unsigned jia = 0, jian = 0, cheng = 0, chu = 0, qian = 0, hou = 0;
87 for (auto it = v.begin(); it != v.end(); ++it) { //遍历v中每个元素,数一共有多少个操作符
88 if (*it == Jia) jia++;
89 else if (*it == Jian) jian++;
90 else if (*it == Chen) cheng++;
91 else if (*it == Chu) chu++;
92 else if (*it == Qian) qian++;
93 else if (*it == Hou) hou++;
94 }
95 // for (auto t : v) //debug
96 // cout << t << "\t" << endl;
97
98 if (jia + jian + cheng + chu == 1) { //最后一步--只算一个算式
99 if (jia == 1) return v[0] + v[2];
100 if (jian == 1) return v[0] - v[2];
101 if (cheng == 1) return v[0] * v[2];
102 if (chu == 1) return v[0] / v[2];
103 }
104 if (qian + hou == 0) { //无括号的情形
105 if (cheng + chu == 0 ) { //无乘除情形
106 vector<double> vv; //对一组数进行操作
107 double re = Count(v[0], v[2], v[1]); //只对一对算式进行操作
108 vv.push_back(re); //将一对算式的结果推入底部,相当于用答案取代了那个算式
109 for (auto i = v.begin() + 3; i != v.end(); ++i) { //将上一个算式后的所有字符添加vv到底部
110 vv.push_back(*i);
111 }
112 return Calculate_Single(vv); //用递归实现--相当于将一处的算式替换成了数字
113 }
114 else { //有乘除--目标:将指针一直前进到乘/除字符的位置t,计算该算式,保存乘/除前面所有的字符,再保存乘除算成的值,再保存乘除后的算式
115 int t; //标志位置-乘或除的位置
116 vector<double> vv; //用来保存计算过乘除的式子
117 for (t = 0; v[t] != Chen && v[t] != Chu; ++t); //推进到乘除的地方
118 double re = Count(v[t-1], v[t+1], v[t]); //计算乘除式子
119 for (int i = 0; i < t-1; i++) { //将乘除前面的式子push_back
120 vv.push_back(v[i]);
121 }
122 vv.push_back(re); //再替换乘除的式子为数值
123 for (auto it = v.begin() + t + 2; it != v.end(); ++it) { //将乘除后面式子保存到vv中
124 vv.push_back(*it);
125 }
126 return Calculate_Single(vv); //递归--一直递归到式子中只有一个式子的情况
127 }
128 }
129 else { //有括号的情况
130 vector<double> vv, vvv; //vv--是保存将括号中计算结束后的式子,vvv--保存括号中的式子并计算出
131 int q, h; //q -- 前括号的位置,h--后括号的位置
132 double re;
133 for (h = 0; v[h] != Hou; ++h); //推进到后括号的位置
134 for (q = h; v[q] != Qian; --q); //后退到前括号的位置
135 for (int i = q + 1; i < h; ++i) //将括号中的式子push到vvv底部
136 vvv.push_back(v[i]);
137 re = Calculate_Single(vvv); //将括号中的式子递归求出
138 for (int i = 0; i < q; i++) { //将前括号中的式子push_back
139 vv.push_back(v[i]);
140 }
141 vv.push_back(re); //将括号中的式子计算出push到vv底部
142 for (auto it = v.begin() + h + 1; it != v.end(); ++it) //将括号后的式子push_back
143 vv.push_back(*it);
144 return Calculate_Single(vv); //再次递归进行计算--一直到只有一个式子的时候终止
145 }
146 cerr << "Bug:Calculate_Single 失效!" << endl;
147 return 0;
148 }
149
150 int main()
151 {
152 vector<double> data;
153 string line;
154 cin >> line;
155 Exchange(data, line);
156 double result = Calculate_Single(data);
157 cout << result << endl;
158 return 0;
159 }
标签:
原文地址:http://www.cnblogs.com/douzujun/p/5475947.html