本周,对于这个结对编程项目,我们取得一些进展。
模块化
首先,我将之前实现的随机生成表达式的程序模块化。在此过程中我顺便复习了一下我忘了许久的面向对象知识。
我把核心功能封装在了一个名为cal_expression的类中。这是实现计算功能的核心模块。
这个模块具有计算分数四则运算,分数化简,将中缀表达式变成后缀表达式,计算后缀表达式等功能。
有了这些功能之后,再加上接收一个string类的表达式并返回string类的结果的功能,就看起来像是一个真正的模块了。
具体代码如下:
1 class FenShu 2 { 3 public: 4 int fenzi; 5 int fenmu; 6 }; 7 8 class cal_expression 9 { 10 public: 11 int flag; 12 string question; 13 string ans; 14 cal_expression() 15 { 16 flag = 0; 17 question = ans = ""; 18 } 19 void input(string s) 20 { 21 question = s; 22 } 23 string output() 24 { 25 return ans; 26 } 27 int lcm(int a,int b) 28 { 29 int i; 30 for(i = max(a,b);i <= a * b;i += max(a,b)) 31 { 32 if(i % min(a,b)== 0) 33 break; 34 } 35 return i; 36 } 37 int gcd(int a,int b) 38 { 39 if(b == 0) 40 return a; 41 else 42 return gcd(b,a % b); 43 } 44 int move_index(int a) 45 { 46 int result = 1; 47 while(a >= 10) 48 { 49 a /= 10; 50 result ++; 51 } 52 return result; 53 } 54 bool cmp(char a,char b) 55 { 56 if((a == '+' || a == '-') && (b == '*' || b == '/')) 57 return false; 58 return true; 59 } 60 FenShu Err() 61 { 62 FenShu result; 63 flag = -1; 64 return result; 65 } 66 FenShu Plus(FenShu a,FenShu b) 67 { 68 FenShu result; 69 int temp = lcm(a.fenmu,b.fenmu); 70 result.fenmu = temp; 71 result.fenzi = temp / a.fenmu * a.fenzi + temp / b.fenmu * b.fenzi; 72 return result; 73 } 74 FenShu Sub(FenShu a,FenShu b) 75 { 76 FenShu result; 77 int temp = lcm(a.fenmu,b.fenmu); 78 result.fenmu = lcm(a.fenmu,b.fenmu); 79 result.fenzi = temp / a.fenmu * a.fenzi - temp / b.fenmu * b.fenzi; 80 return result; 81 } 82 FenShu Mul(FenShu a,FenShu b) 83 { 84 FenShu result; 85 result.fenzi = a.fenzi * b.fenzi; 86 result.fenmu = a.fenmu * b.fenmu; 87 return result; 88 } 89 FenShu Div(FenShu a,FenShu b) 90 { 91 FenShu result; 92 if (b.fenzi == 0) 93 { 94 return Err(); 95 } 96 result.fenzi = a.fenzi * b.fenmu; 97 result.fenmu = a.fenmu * b.fenzi; 98 return result; 99 } 100 101 FenShu calculate(FenShu a,FenShu b,char ope) 102 { 103 switch(ope) 104 { 105 case '+': 106 return Plus(a,b); 107 case '-': 108 return Sub(a,b); 109 case '*': 110 return Mul(a,b); 111 case '/': 112 return Div(a,b); 113 default: 114 return Err(); 115 } 116 } 117 FenShu simplify(FenShu a) 118 { 119 FenShu result; 120 int g = gcd(a.fenmu,a.fenzi); 121 result.fenmu = a.fenmu / g; 122 result.fenzi = a.fenzi / g; 123 return result; 124 } 125 126 string transfer(string str) 127 { 128 stack<char> ope; 129 string result = ""; 130 unsigned long len = str.length(); 131 for(int i = 0;i < len;i ++) 132 { 133 switch(str.at(i)) 134 { 135 case '+': 136 case '-': 137 case '*': 138 case '/': 139 while(!ope.empty() && (ope.top() != '(') && cmp(ope.top(),str.at(i))) 140 { 141 result += ope.top(); 142 ope.pop(); 143 } 144 ope.push(str.at(i)); 145 break; 146 case '(': 147 ope.push(str.at(i)); 148 break; 149 case ')': 150 while(!ope.empty()) 151 { 152 char temp = ope.top(); 153 ope.pop(); 154 if(temp == '(') 155 break; 156 else 157 result += temp; 158 } 159 break; 160 default: 161 if( !('0'<=str.at(i) && str.at(i)<='9')) 162 return "error"; 163 else 164 { 165 stringstream stream,stream2; 166 int temp; 167 stream << str.substr(i,len - i); 168 stream >> temp; 169 int l = move_index(temp); 170 i += (l - 1); 171 stream2 << temp; 172 string n; 173 stream2 >> n; 174 result.append(n); 175 result += ' '; 176 } 177 } 178 } 179 while(!ope.empty()) 180 { 181 result += ope.top(); 182 ope.pop(); 183 } 184 return result; 185 } 186 string toString(FenShu res) 187 { 188 string str,buf; 189 stringstream stream,stream2; 190 stream << res.fenzi; 191 stream >> str; 192 if(res.fenmu != 1) 193 { 194 str += '/'; 195 stream2 << res.fenmu; 196 stream2 >> buf; 197 str += buf; 198 } 199 return str; 200 } 201 202 string cal() 203 { 204 question = transfer(question); 205 stack<FenShu> num; 206 if (question == "error") 207 { 208 return "error"; 209 } 210 unsigned long len = question.length(); 211 for(int i = 0;i < len;i ++) 212 { 213 char temp = question.at(i); 214 if(temp >= '0' && temp <= '9') 215 { 216 stringstream stream; 217 int temp; 218 stream << question.substr(i,len - i); 219 stream >> temp; 220 int l = move_index(temp); 221 i += l; 222 FenShu fs; 223 fs.fenzi = temp; 224 fs.fenmu = 1; 225 num.push(fs); 226 } 227 else 228 { 229 FenShu num2 = num.top(); 230 num.pop(); 231 FenShu num1 = num.top(); 232 num.pop(); 233 FenShu result = calculate(num1,num2,question.at(i)); 234 if (flag == -1) 235 { 236 return "error"; 237 } 238 num.push(result); 239 } 240 } 241 FenShu fs = simplify(num.top()); 242 return toString(fs); 243 244 } 245 246 bool get_res(string &buf) 247 { 248 string res = cal(); 249 if(res == "error") 250 return false; 251 buf = res; 252 return true; 253 } 254 255 };
测试
之后,感谢我们组另一位同学(13070040张博闻)用在软件测试课上的学过的专业知识完成了对这个模块的测试。
具体分为白盒测试和黑盒测试。
详情请参见 http://www.cnblogs.com/zbinks
目前的情况就是这样。