四则运算题3

基本设计思路:

1.引入数据结构,对混合四则运算式进行求解;

2.在四则运算题2的基础上添加,计算功能;

3.将计算式保存至文本;

4.将运算式正确结果与输入结果进行对比,判断正误;

5.将答题情况进行统计;

遇到困难:

1.对混合四则运算式进行求解时,需要用到之前学过的数据结构相关知识,很难!

2.分式的计算结果判断问题,最后选择对无限小数进行保留两位的方法。

 

队员:王楗  http://home.cnblogs.com/u/wangjianly/

结对编程,合作照:

  1 //四则运算3
  2 //成员:张勋 王楗
  3 #include <iostream>
  4 #include <fstream>
  5 #include <string>
  6 #include <cmath>
  7 #include <sstream>
  8 #include <time.h>
  9 using namespace std;
 10 
 11 #define true 1
 12 #define false 0
 13 #define OPSETSIZE 8
 14 
 15 typedef int Status;
 16 unsigned char Prior[8][8] =
 17 { // 运算符优先级表
 18     // '+' '-' '*' '/' '(' ')' '#' '^'
 19     /*'+'*/'>', '>', '<', '<', '<', '>', '>', '<',
 20     /*'-'*/'>', '>', '<', '<', '<', '>', '>', '<',
 21     /*'*'*/'>', '>', '>', '>', '<', '>', '>', '<',
 22     /*'/'*/'>', '>', '>', '>', '<', '>', '>', '<',
 23     /*'('*/'<', '<', '<', '<', '<', '=', ' ', '<',
 24     /*')'*/'>', '>', '>', '>', ' ', '>', '>', '>',
 25     /*'#'*/'<', '<', '<', '<', '<', ' ', '=', '<',
 26     /*'^'*/'>', '>', '>', '>', '<', '>', '>', '>'
 27 };
 28 typedef struct StackChar
 29 {
 30     char c;
 31     struct StackChar *next;
 32 }SC;       //StackChar类型的结点SC
 33 typedef struct StackFloat
 34 {
 35     float f;
 36     struct StackFloat *next;
 37 }SF;       //StackFloat类型的结点SF
 38 
 39 SC *Push(SC *s, char c)          //SC类型的指针Push,返回p
 40 {
 41     SC *p = (SC*)malloc(sizeof(SC));
 42     p->c = c;
 43     p->next = s;
 44     return p;
 45 }
 46 SF *Push(SF *s, float f)        //SF类型的指针Push,返回p
 47 {
 48     SF *p = (SF*)malloc(sizeof(SF));
 49     p->f = f;
 50     p->next = s;
 51     return p;
 52 }
 53 SC *Pop(SC *s)    //SC类型的指针Pop
 54 {
 55     SC *q = s;
 56     s = s->next;
 57     free(q);
 58     return s;
 59 }
 60 SF *Pop(SF *s)      //SF类型的指针Pop
 61 {
 62     SF *q = s;
 63     s = s->next;
 64     free(q);
 65     return s;
 66 }
 67 
 68 
 69 float Operate(float a, unsigned char theta, float b)      //计算函数Operate
 70 {
 71     switch (theta)
 72     {
 73     case '+': return a + b;
 74     case '-': return a - b;
 75     case '*': return a*b;
 76     case '/': return a / b;
 77     case '^': return pow(a, b);
 78     default: return 0;
 79     }
 80 }
 81 
 82 char OPSET[OPSETSIZE] = { '+', '-', '*', '/', '(', ')', '#', '^' };
 83 Status In(char Test, char *TestOp)
 84 {
 85     int Find = false;
 86     for (int i = 0; i < OPSETSIZE; i++)
 87     {
 88         if (Test == TestOp[i])
 89             Find = true;
 90     }
 91     return Find;
 92 }
 93 
 94 Status ReturnOpOrd(char op, char *TestOp)
 95 {
 96     for (int i = 0; i < OPSETSIZE; i++)
 97     {
 98         if (op == TestOp[i])
 99             return i;
100     }
101 }
102 
103 char precede(char Aop, char Bop)
104 {
105     return Prior[ReturnOpOrd(Aop, OPSET)][ReturnOpOrd(Bop, OPSET)];
106 }
107 
108 
109 //计算运算式数值:EvaluateExpression
110 //-------------------------------------------------------------
111 float EvaluateExpression(char* MyExpression)
112 {
113     // 算术表达式求值的算符优先算法
114     // 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合
115     SC *OPTR = NULL;       // 运算符栈,字符元素
116     SF *OPND = NULL;       // 运算数栈,实数元素
117     char TempData[20];
118     float Data, a, b;
119     char theta, *c, Dr[] = { '#', '\0' };
120     OPTR = Push(OPTR, '#');
121     c = strcat(MyExpression, Dr);
122     strcpy(TempData, "\0");//字符串拷贝函数
123     while (*c != '#' || OPTR->c != '#')
124     {
125         if (!In(*c, OPSET))
126         {
127             Dr[0] = *c;
128             strcat(TempData, Dr);           //字符串连接函数
129             c++;
130             if (In(*c, OPSET))
131             {
132                 Data = atof(TempData);       //字符串转换函数(double)
133                 OPND = Push(OPND, Data);
134                 strcpy(TempData, "\0");
135             }
136         }
137         else    // 不是运算符则进栈
138         {
139             switch (precede(OPTR->c, *c))
140             {
141             case '<': // 栈顶元素优先级低
142                 OPTR = Push(OPTR, *c);
143                 c++;
144                 break;
145             case '=': // 脱括号并接收下一字符
146                 OPTR = Pop(OPTR);
147                 c++;
148                 break;
149             case '>': // 退栈并将运算结果入栈
150                 theta = OPTR->c; OPTR = Pop(OPTR);
151                 b = OPND->f; OPND = Pop(OPND);
152                 a = OPND->f; OPND = Pop(OPND);
153                 OPND = Push(OPND, Operate(a, theta, b));
154                 break;
155             } //switch
156         }
157     } //while
158     return OPND->f;
159 }
160 //符号函数
161 //-------------------------------------------------------------
162 string fuhao(int chu)
163 {
164     string fu;
165     int num_3;
166     if (chu == 1)
167     {
168         num_3 = (rand() % 100) % 4;
169         if (num_3 == 0) fu = '+';
170         else if (num_3 == 1) fu = '-';
171         else if (num_3 == 2) fu = '*';
172         else fu = '/';
173         return fu;
174     }
175     else
176     {
177         num_3 = (rand() % 20) % 2;
178         if (num_3 == 0) fu = '+';
179         else   fu = '-';
180         return fu;
181     }
182 }
183 //分数函数
184 //-------------------------------------------------------------
185 string  fenshu()
186 {
187     int a1 = 0, b1 = 0, a2 = 0, b2 = 0;
188     a1 = (rand() % (97));
189     b1 = (rand() % (100 - a1)) + a1 + 1;
190     a2 = (rand() % (97));
191     b2 = (rand() % (100 - a2)) + a2 + 1;
192     string first_a1, second_b1;
193     string first_a2, second_b2;
194     first_a1 = to_string(a1);
195     second_b1 = to_string(b1);
196     first_a2 = to_string(a2);
197     second_b2 = to_string(b2);
198     string all1 = "";
199     //随机产生四则运算符
200     int fu = 0;
201     fu = (rand() % 100) % 2;
202     if (fu == 0)
203     {
204         all1 = "(" + first_a1 + "/" + second_b1 + ")" + "+" + "(" + first_a2 + "/" + second_b2 + ")" + "=";
205     }
206     else if (fu == 1)
207     {
208         all1 = "(" + first_a1 + "/" + second_b1 + ")" + "-" + "(" + first_a2 + "/" + second_b2 + ")" + "=";
209     }
210     else if (fu == 2)
211     {
212         all1 = "(" + first_a1 + "/" + second_b1 + ")" + "*" + "(" + first_a2 + "/" + second_b2 + ")" + "=";
213     }
214     else
215     {
216         all1 = "(" + first_a1 + "/" + second_b1 + ")" + "/" + "(" + first_a2 + "/" + second_b2 + ")" + "=";
217     }
218     return all1;
219 }
220 //运算函数
221 //-------------------------------------------------------------
222 string yunsuan(int chu, int kuohao, int range)
223 {
224     int num_1, num_2;
225     int geshu;
226     string str_first, str_second;
227     string all = "";
228     int ch1;
229     geshu = (rand() % (8) + 2);
230     ofstream fout;
231     for (int i = 1; i <= geshu; i++)
232     {
233         num_1 = (rand() % (range)) + 1;
234         str_first = to_string(num_1);
235         num_2 = (rand() % (range)) + 1;
236         str_second = to_string(num_2);
237         if (kuohao == 1)
238         {
239             ch1 = (rand() % (4)) + 1;
240             switch (ch1){
241             case 1:
242             {
243                       if (all == "") { all = str_first + fuhao(chu) + str_second; }
244                       else  { all = str_first + fuhao(chu) + all; }
245             }break;
246             case 2:
247             {
248                       if (all == "") { all = str_second + fuhao(chu) + str_first; }
249                       else { all = all + fuhao(chu) + str_first; }
250             }break;
251             case 3:
252             {
253                       if (all == "") { all = "(" + str_first + fuhao(chu) + str_second + ")"; }
254                       else { all = "(" + str_first + fuhao(chu) + all + ")"; }
255             }break;
256             case 4:
257             {
258                       if (all == ""){ all = "(" + str_second + fuhao(chu) + str_first + ")"; }
259                       else { all = "(" + all + fuhao(chu) + str_first + ")"; }
260             }break;
261             }
262         }
263         else
264         {
265             ch1 = (rand() % (2)) + 1;
266             switch (ch1){
267             case 1:
268             {
269                       if (all == "") { all = str_first + fuhao(chu) + str_second; }
270                       else  { all = str_first + fuhao(chu) + all; }
271             }break;
272             case 2:
273             {
274                       if (all == "") { all = str_second + fuhao(chu) + str_first; }
275                       else { all = all + fuhao(chu) + str_first; }
276             }break;
277             }
278         }
279     }
280     string c = all.substr(0, 1);
281     string b = all.substr(all.length() - 1, all.length());
282     if (c == "("&&b == ")")
283     {
284         all = all.substr(1, all.length() - 2);
285         return all + "=";
286     }
287     else
288     {
289         return  all + "=";
290     }
291 }
292 
293 
294 //主函数
295 //-------------------------------------------------------------
296 int main(void)
297 {
298     srand(time(NULL));
299     int chu, kuohao, range;
300     int calculate_fenshu = 0;//统计分数个数
301     int Y_N;
302     int count;//设置循环次数
303     int disport;
304     ofstream file;
305     ofstream file_result;
306     FILE *f1;
307     cout << "有无除法:(1:有,2:无)" << endl;
308     cin >> chu;
309     cout << "是否有括号:(1:有,2:无)" << endl;
310     cin >> kuohao;
311     cout << "请输入数值的范围:" << endl;
312     cout << "1-";
313     cin >> range;
314     cout << "请输入一共有多少个算式:" << endl;
315     cin >> count;
316     //分数
317     cout << "是否产生分数(产生真分数):(1:是,2:否)" << endl;
318     cin >> Y_N;
319     file.open("test.txt");
320     //************将生成的算式保存在文件中**********************
321     if (Y_N == 1)
322     {
323         cout << "产生的" << count << "个算式中,希望有几个分数式:" << endl;
324         cout << "分数式结果请保留两位小数:" << endl;
325         cin >> calculate_fenshu;
326         for (int m = 0; m < calculate_fenshu; m++)
327         {
328             file << fenshu() << endl;
329         }
330     }
331 
332     for (int i = calculate_fenshu; i <= count; i++)
333     {
334         file << yunsuan(chu, kuohao, range) << endl;
335         //fenshu();
336     }
337     file.close();
338     //*************************
339     char a[255];
340     double cin_result;
341     int jishu = 0;
342     cout << "是否将生成的算式以及结果输出到文件:(1:是, 2:否)" << endl;
343     cin >> disport;
344     cout << "生成的四则运算式为:" << endl;
345     cout << endl;
346     if (disport == 1)
347     {
348         file_result.open("rusult.txt");
349         file_result << "***************************四则运算式****************************" << endl;
350         if (f1 = fopen("test.txt", "r"))
351         {
352             for (int j = 0; j < count; j++)
353             {
354                 fscanf(f1, "%s", a); //文件内容一行不要大于255个字符
355 
356                 cout << j + 1 << ".";
357                 cout << a << endl;
358                 file_result << j + 1 << "." << a << endl;
359                 cout << "请输入结果:" << endl;
360                 file_result << "请输入结果:" << endl;
361                 cin >> cin_result;
362                 file_result << cin_result;
363                 file_result << endl;
364                 if (fabs(cin_result - EvaluateExpression(a)) < 1e-2)
365                 {
366                     cout << "结果正确" << endl;
367                     file_result << "结果正确" << endl;
368                     jishu = jishu + 1;
369                 }
370                 else
371                 {
372                     cout << "结果错误,正确答案为:" << EvaluateExpression(a) << endl;
373                     file_result << "结果错误,正确答案为:" << EvaluateExpression(a) << endl;
374                 }
375             }
376             cout << "您一共答对" << jishu << "道题,答错" << count - jishu << "道题。" << endl;
377             file_result << "您一共答对" << jishu << "道题,答错" << count - jishu << "道题。" << endl;
378             fclose(f1);
379         }
380         file.close();
381     }
382     else
383     {
384 
385         if (f1 = fopen("test.txt", "r"))
386         {
387             for (int j = 0; j < count; j++)
388             {
389                 fscanf(f1, "%s", a); //文件内容一行不要大于255个字符
390                 cout << j + 1 << ".";
391                 cout << a << endl;
392                 cout << "请输入结果:" << endl;
393                 cin >> cin_result;
394                 if (fabs(cin_result - EvaluateExpression(a)) < 1e-2)
395                 {
396                     cout << "结果正确" << endl;
397                     jishu = jishu + 1;
398                 }
399                 else
400                 {
401                     cout << "结果错误,正确答案为:" << EvaluateExpression(a) << endl;
402                 }
403             }
404             cout << "您一共答对" << jishu << "道题,答错" << count - jishu << "道题。" << endl;
405             fclose(f1);
406         }
407         file.close();
408     }
409     system("DEL /f test.txt");
410     return 0;
411 }

 

程序运行结果如图:

对于四则运算题目要求的选择如下:

按照此要求,产生如下四则运算式,并计算:

由此,得出答题统计情况如下:

同时,输出到文件中的结果如下:

再次运行结果如下:

输出到文本为:

 

本次结对开发的项目开发总结如下:

<

项目计划 总 结:             
日期\任务 听课 编写程序 查阅资料 日总计  
星期一 2 1 1 4  
星期二   2 1 3  
星期三   2 1 3  
星期四 2 2 1 5  
星期五   5 1 6  
星期六          
星期日          
周总计 4 12 5 21  

<

时间记录日志:               
             
日期 开始时间 结束时间 中断时间 静时间 活动 备注
3月14日 14:00 15:50 10 100 听课 软件工程
  19:30 21:50 10 180 编写程序 编写程序架构、增加新功能&查资料
3月15日 18:20 21:45 25 135 编写程序  
3月16日 14:30 17:40 10 180 查阅资料 学习数据结构相关知识
          编写程序  
3月17日 14:00 15:50 10 100 听课 软件工程
  18:20 21:20   180 编写程序 调试程序寻找错误地方
3月18日 14:10 20:40 90 300 编写程序 调试程序为主,并修改部分功能,规范代码
  21:00 22:00   60 看书  
3月19日 8:00 9:00   60 调试 最终调试

<

缺陷记录日志:          
         
日期 编号 引入阶段 排除阶段 修复时间&问题描述
3月14日 1 编码 编译 1.5小时,计算函数的数据结构出错
3月15日 2 编码 编码 1小时,产生的随机算式输出到文本中,并进行读取时出错。
3月16日 3 编码 编译 1.5小时,用计算函数调试产生的文本中的算式,不能正确计算出结果
3月17日 4 编码 编译 2小时,分数式无法正确判断结果
3月18日 5 编码 编译 3.5小时,保存文件时,无法将答题结果输入到文件中;部分代码不规范
3月19日 6 编码 编译  
posted @ 2016-03-18 10:01  勋爵|X-knight  阅读(223)  评论(2编辑  收藏  举报