zoukankan      html  css  js  c++  java
  • 结对项目——自动生成小学四则运算题目

    一、Github项目地址

    地址: https://github.com/Sheaxx/Myapp

    结对成员:18软4方晓莹 3218005126 ,18软4黄芯悦 3218005128 

     

    二、项目概况

    项目说明

    自然数:0, 1, 2, …。

    • 真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
    • 运算符:+, −, ×, ÷。
    • 括号:(, )。
    • 等号:=。
    • 分隔符:空格(用于四则运算符和等号前后)。
    • 算术表达式:

      e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),

      其中e, e1和e2为表达式,n为自然数或真分数。

    • 四则运算题目:e = ,其中e为算术表达式。

     

    项目需求

      1. 使用 -n 参数控制生成题目的个数。(实现)

        例如: Myapp.exe -n 10  

        //将生成10个题目。

      2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围。(实现)

        例如: Myapp.exe -r 10  

        //将生成10以内(不包括10)的四则运算题目。

        //该参数可以设置为1或其他自然数。

        //该参数必须给定,否则程序报错并给出帮助信息。

      3. 生成的题目中计算过程不能产生负数。(实现)

        也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2

      4. 生成的题目中如果存在形如 e1÷ e的子表达式,那么其结果应是真分数。(实现)

      5. 每道题目中出现的运算符个数不超过3个。(实现)

      6. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一

        道题目。

       (未完全实现,仅实现排除完全重复的题目)

        例如:

        ① 23 + 45 = 和45 + 23 = 是重复的题目。

        ② 6 × 8 = 和8 × 6 = 也是重复的题目。

        ③ 3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就

         是3+(2+1)。

        ④ 但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过

         有限次交换变成同一个题目。

       7. 生成的题目存入执行程序的当前目录下的Exercises.txt文件。(实现)

         格式如下:

        1. 四则运算题目1
        2. 四则运算题目2

             ……

         其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。

       8. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。(实现)

         格式如下:

        1. 答案1
        2. 答案2

             ……

         特别的,真分数的运算如下例所示:1/6 + 1/8 = 7/24。

       9. 程序应能支持一万道题目的生成。(实现)

       10. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。(实现)

         输入参数:Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt

          统计结果输出到文件Grade.txt,格式如下:

             Correct: 5 (1, 3, 5, 7, 9)

            Wrong: 5 (2, 4, 6, 8, 10)

         其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目

         都是按照顺序编号的符合规范的题目。

     

    三、PSP表格

    PSP2.1

    Personal Software Process Stages

    预估耗时(分钟)

    实际耗时(分钟)

    Planning

    计划

       

    · Estimate

    · 估计这个任务需要多少时间

    600+650

    480+550

    Development

    开发

       

    · Analysis

    · 需求分析 (包括学习新技术)

    60+50

    50+50

    · Design Spec

    · 生成设计文档

    30+30

    25+25

    · Design Review

    · 设计复审 (和同事审核设计文档)

    30+30

    20+20

    · Coding Standard

    · 代码规范 (为目前的开发制定合适的规范)

    10+10

    10+10

    · Design

    · 具体设计

    60+55

    80+70

    · Coding

    · 具体编码

    480+500

    520+550

    · Code Review

    · 代码复审

    40+45

    30+35

    · Test

    · 测试(自我测试,修改代码,提交修改)

    60+60

    80+75

    Reporting

    报告

       

    · Test Report

    · 测试报告

    40+40

    30+30

    · Size Measurement

    · 计算工作量

    10+10

    10+10

    · Postmortem & Process Improvement Plan

    · 事后总结, 并提出过程改进计划

    10+10

    10+10

     

    合计

    1430+1490

    1345+1435

     

    四、效能分析

    改进思路

    1. 化简计算:一开始选择把整数和分数的计算分为两个函数,后来经过讨论,发现整数和分数的计算其实是一致的,前者是分母为1的情况,后者是分母不为0且不为1的情况。基于讨论,合并了两个函数,并化简了计算过程。

    2. 模块化:整个项目中有很多部分都是重复调用的,比如分数化简、获取随机数、生成运算数等,将重复调用的内容独立出一个函数,作为接口在需要的地方调用,实现了模块化的思想。

    3. 需求分析:两人讨论在讨论需求时,认识到程序的实现过程其实和需求10是互逆的。由此,根据我们的实现过程,反向实现需求10。

     

    性能分析

    对生成1W题的情况进行了相关的性能分析,如下图所示:

     

     

     

    函数展示

    以下是消耗最大的函数代码展示:

      1 //运算菜单
      2 void menu(int n,int r,char str1[],char str2[],bool flag) {
      3     FILE* fp1, * fp2, * fp3, * fp4, * fp5;
      4     errno_t err1, err2, err3, err4, err5;
      5     int select = 0, select1 = 0;  //随机选定分数或整数运算
      6     int i = 0, j = 0, k = 0, m = 0, p = 0, x = 0, a = 0;
      7     int y1 = 0, y2 = 0, y3 = 0;  //打印判定结果的参数
      8     int mark = 0, tab = 0;  //分数和括号的判定标记
      9     int mo[4] = { 0 };
     10     int mi = 0;
     11     int num[7] = { 0 }, t[8] = { 0 };
     12     int c[100] = { 0 }, w[100] = { 0 };
     13     char s[10] = { '\0' };  //存放运算符
     14     char ef[100] = { '\0' };  //存放题目
     15     char af[20] = { '\0' };  //存放答案
     16     char cmp[20] = { '\0' };
     17     char grade[10] = { '\0' };
     18     err1 = fopen_s(&fp1, "Exercises.txt", "w+");
     19     err2 = fopen_s(&fp2, "Answers.txt", "w+");
     20     err3 = fopen_s(&fp3, str1, "r");
     21     err4 = fopen_s(&fp4, str2, "r");
     22     err5 = fopen_s(&fp5, "Grade.txt", "w+");
     23 
     24     srand((unsigned long)time(0));
     25 
     26     if (fp1 == NULL || fp2 == NULL) {
     27         printf("文件不存在。\n");
     28     }
     29     else if (fp3 != NULL && fp4 != NULL && flag == false) {
     30         //获取题目和答案
     31         while (fgets(ef, sizeof(ef) - 1, fp3) && fgets(af, sizeof(af) - 1, fp4)) {
     32             j = 0; k = 0; m = 0; p = 0; tab = 0; mark = 0;  //初始化
     33             while (j >= '0' && j <= '9')  j++;
     34             j += 4;  //指到序号后的数字的第一位
     35             for (; j < strlen(ef); j++) {
     36                 if (ef[j] >= '0' && ef[j] <= '9') {
     37                     if (mark == 0 || mark == 1) {
     38                         mi = ef[j] - 48;
     39                         t[k] = t[k] * 10 + mi;
     40                         if (ef[j + 1] == ' ' || ef[j + 1] == '\n' || ef[j + 1] == '\0' || ef[j + 1] == ')') {
     41                             if (mark == 0)t[++k] = 1;  //说明是整数,分母置为1
     42                             else mark = 0;  //说明分母的数字结束
     43                             k++;
     44                             if (k % 2 == 0 && k != 0)p++;  //储存分子的数组指向下一位
     45                         }
     46                         else if (ef[j + 1] == '/') {  //分子数字结束
     47                             mark = 1;
     48                             k++;
     49                         }
     50                         else if (ef[j + 1] == 39)mark = 2;  //带分数
     51                     }
     52                     else if (mark == 2) {
     53                         mi = ef[j] - 48;
     54                         mo[p] = 10 * mo[p] + mi;
     55                         if (ef[j + 1] == '/') {  //带分数分子数字结束
     56                             k++;
     57                             mark = 1;
     58                         }
     59                     }
     60                 }
     61                 else if ((ef[j] == '+' || ef[j] == '-' || ef[j] == '*' || ef[j] == '/') && ef[j + 1] == ' ') {
     62                     s[m++] = ef[j];
     63                 }
     64                 else if (ef[j] == '(') {
     65                     if (k == 0)tab = 1;  //第一个数之前的括号
     66                     else if (k == 2)tab = 2;  //第二个数之前的括号
     67                 }
     68             }
     69 
     70             for (m = 0, p = 0; m < k - 1; m += 2, p++) {
     71                 if (mo[p] != 0)t[m] = t[m] * t[m + 1] + mo[p];
     72             }//带分数变成假分数 整数部分乘分母加上分子
     73 
     74             if (tab == 0) {
     75                 //无括号
     76                 if (k == 4)  select = 0;
     77                 else if (k == 6) {
     78                     select = 1;
     79                     a = 3;
     80                 }
     81                 else if (k == 8)  select = 2;
     82             }
     83             else if (tab == 1) {
     84                 //3个运算数,前括
     85                 select = 1;
     86                 a = 1;
     87             }
     88             else if (tab == 2) {
     89                 //3个运算数,后括
     90                 select = 1;
     91                 a = 2;
     92             }
     93 
     94             num[0] = order(s, select, a);
     95             digit_integer(i + 1, cmp, y3);
     96             //拼接序号
     97             cmp[y3++] = '.';
     98             cmp[y3++] = ' ';
     99             cmp[y3++] = ' ';
    100             cmp[y3++] = '\0';
    101             cmp[strlen(cmp)] = '\0';
    102             strcat_s(cmp, 20, classify(num, t, s, r, i, fp1, fp2, flag));
    103             y3 = strlen(cmp);
    104             cmp[y3] = '\n';  //换行符结尾
    105             cmp[++y3] = '\0';  //数组结尾
    106             if (strcmp(af, cmp) == 0)c[y1++] = i + 1;
    107             else w[y2++] = i + 1;
    108             for (j = 0; j < 8; j++) t[j] = 0;
    109             for (j = 0; j < 4; j++) mo[j] = 0;
    110             for (j = 0; j < 10; j++) s[j] = '\0';
    111             y3 = 0;
    112             i++;
    113         }
    114         fclose(fp3);
    115         fclose(fp4);
    116 
    117         //打印正确结果
    118         printf("\nCorrect: %d (", y1);
    119         for (y3 = 0; y3 < y1 - 1; y3++)
    120             printf("%d,", c[y3]);
    121         printf("%d)\n", c[y3]);
    122 
    123         //打印错误结果
    124         printf("Wrong: %d (", y2);
    125         for (y3 = 0; y3 < y2 - 1; y3++)
    126             printf("%d,", w[y3]);
    127         printf("%d)\n", w[y3]);
    128 
    129         printf("\n判定完成!判定结果已存入Grade.txt中。\n");
    130 
    131         j = 0;
    132         fputs("Correct: ", fp5);
    133         digit_integer(y1, grade, j);
    134         fputs(grade, fp5);
    135         fputs(" (", fp5);
    136         for (y3 = 0; y3 <= y1 - 1; y3++) {
    137             j = 0;
    138             digit_integer(c[y3], grade, j);
    139             fputs(grade, fp5);
    140             if (y3 + 1 != y1)fputs(",", fp5);
    141         }
    142         if (c[0] == 0)fputs("0", fp5);
    143         fputs(")\n", fp5);
    144 
    145         j = 0;
    146         fputs("Wrong: ", fp5);
    147         digit_integer(y2, grade, j);
    148         fputs(grade, fp5);
    149         fputs(" (", fp5);
    150         for (y3 = 0; y3 <= y2 - 1; y3++) {
    151             j = 0;
    152             digit_integer(w[y3], grade, j);
    153             fputs(grade, fp5);
    154             if (y3 + 1 != y2)fputs(",", fp5);
    155         }
    156         if (w[0] == 0)fputs("0", fp5);
    157         fputs(")\n", fp5);
    158     }
    159     else if ((fp3 == NULL || fp4 == NULL) && flag == false) {
    160         printf("未找到指定文件。\n");
    161     }
    162     else {
    163         while (i < n) {
    164             select1 = rand() % 30;
    165             num[0] = numcreate(t, select1 % 3, r, s);  //随机生成数
    166             strcpy_s(cmp, classify(num, t, s, r, i, fp1, fp2, flag));
    167             if (strcmp(cmp, "-1") == 0)  continue;
    168             else i++;
    169         }
    170         printf("\n成功生成%d道四则运算题,题目和答案已存入Exercises.txt和Answers.txt中。\n", n);
    171         fclose(fp1);
    172         fclose(fp2);
    173     }
    174 }

    五、设计实现过程

    六、代码说明

    此处展示了运算情况的分析、加减乘除的实现和整数除法共三段关键代码。

      1 //分析运算情况并写入文件
      2 char* classify(int num[], int t[], char s[], int r, int i, FILE* fp1, FILE* fp2,bool flag) {
      3     int j = 0, k = 0, m = 0, x = 0, l = 0;
      4     int tag = 1; //tag=1是第一个数,tag=2是后边的数,tag=3是答案
      5     int num1[7] = { 0 };
      6     int str[3] = { 0 };  //暂时存放分数的三部分
      7     char c[10] = { '\0' };  //序号
      8     char e[100] = { '\0' };  //题目
      9     char e1[50] = { '\0' }, e2[50] = { '\0' };  //有括号的拼接式
     10     char a[20] = { '\0' };  //答案
     11     char wrong[5] = "-1";
     12 
     13     if (num[0] == 0) {  //两个运算数
     14         while (j < 4) {
     15             num[j + 1] = t[j];
     16             j++;
     17         }
     18         if (arithmetic_fraction(num, s[0], r, tag, e, k, str) == -1)
     19             return wrong;
     20     }
     21     else if (num[0] == 1 || num[0] == 3) {  //三个运算数 按顺序从左到右运算
     22         while (j < 4) {
     23             num[j + 1] = t[j];
     24             j++;
     25         }
     26         if (num[0] == 1) {
     27             e[k++] = '(';
     28         }
     29         if (arithmetic_fraction(num, s[0], r, tag, e, k, str) == -1)
     30             return wrong;
     31         num[1] = num[5];
     32         num[2] = num[6];
     33         num[3] = t[4];
     34         num[4] = t[5];
     35         tag = 2;
     36         if (num[0] == 1) {
     37             e[k++] = ')';
     38         }
     39         if (arithmetic_fraction(num, s[1], r, tag, e, k, str) == -1)
     40             return wrong;
     41     }
     42     else if (num[0] == 2 || num[0] == 5) {  //三个运算数 右边两个数先运算
     43         j = 1;
     44         while (j < 5) {
     45             num[j] = t[j + 1];
     46             j++;
     47         }
     48         e1[k++] = '(';
     49         if (arithmetic_fraction(num, s[1], r, tag, e1, k, str) == -1)
     50             return wrong;
     51         e1[k++] = ')';
     52         e1[k] = '\0';
     53         num[1] = t[0];
     54         num[2] = t[1];
     55         num[3] = num[5];
     56         num[4] = num[6];
     57         tag = 1;
     58         k = 0;
     59         l = arithmetic_fraction(num, s[0], r, tag, e, k, str);
     60         if (l == -1)return wrong;
     61         e[l] = '\0';
     62         strcat_s(e, e1);
     63         l = strlen(e);
     64         e[l] = '\0';
     65     }
     66     else if (num[0] == 6) {  //四个运算数 按顺序运算
     67         while (j < 4) {
     68             num[j + 1] = t[j];
     69             j++;
     70         }
     71         if (arithmetic_fraction(num, s[0], r, tag, e, k, str) == -1)
     72             return wrong;
     73         num[1] = num[5];
     74         num[2] = num[6];
     75         num[3] = t[4];
     76         num[4] = t[5];
     77         tag = 2;
     78         if (arithmetic_fraction(num, s[1], r, tag, e, k, str) == -1)
     79             return wrong;
     80         num[1] = num[5];
     81         num[2] = num[6];
     82         num[3] = t[6];
     83         num[4] = t[7];
     84         tag = 2;
     85         if (arithmetic_fraction(num, s[2], r, tag, e, k, str) == -1)
     86             return wrong;
     87     }
     88     else if (num[0] == 7) {  //四个运算数 先算中间两个数
     89         j = 1;
     90         while (j < 5) {
     91             num[j] = t[j + 1];
     92             j++;
     93         }
     94         if (arithmetic_fraction(num, s[1], r, tag, e1, k, str) == -1)
     95             return wrong;
     96         num[1] = t[0];
     97         num[2] = t[1];
     98         num[3] = num[5];
     99         num[4] = num[6];
    100         tag = 1;
    101         k = 0;
    102         l = arithmetic_fraction(num, s[0], r, tag, e, k, str);
    103         if (l == -1)return wrong;
    104         e[l] = '\0';
    105         strcat_s(e, e1);
    106         k = l = strlen(e);
    107         e[l] = '\0';
    108         num[1] = num[5];
    109         num[2] = num[6];
    110         num[3] = t[6];
    111         num[4] = t[7];
    112         tag = 2;
    113         l = arithmetic_fraction(num, s[2], r, tag, e, k, str);
    114         if (l == -1)return wrong;
    115         e[k] = '\0';
    116     }
    117     else if (num[0] == 8 || num[0] == 10) {  //四个运算数 先算前后 再中间运算
    118         while (j < 4) {
    119             num1[j + 1] = t[j];
    120             j++;
    121         }
    122         j = 1;
    123         while (j < 5) {
    124             num[j] = t[j + 3];
    125             j++;
    126         }
    127         l = arithmetic_fraction(num1, s[0], r, tag, e1, k, str);
    128         if (l == -1)return wrong;
    129         k = 0;
    130         tag = 1;
    131         l = arithmetic_fraction(num, s[2], r, tag, e2, k, str);
    132         if (l == -1)return wrong;
    133         e[0] = '\0';
    134         strcat_s(e, e1);
    135         k = strlen(e);
    136         signstrcat(s[1], e, k);
    137         strcat_s(e, e2);
    138         num[1] = num1[5];
    139         num[2] = num1[6];
    140         num[3] = num[5];
    141         num[4] = num[6];
    142         k = 0;
    143         tag = 2;
    144         l = arithmetic_fraction(num, s[1], r, tag, e1, k, str);
    145         if (l == -1)return wrong;
    146     }
    147     else if (num[0] == 9) {  //四个运算数 先算后面三个数
    148         j = 1;
    149         while (j < 5) {
    150             num[j] = t[j + 1];
    151             j++;
    152         }
    153         l = arithmetic_fraction(num, s[1], r, tag, e1, k, str);
    154         if (l == -1)return wrong;
    155         num[1] = num[5];
    156         num[2] = num[6];
    157         num[3] = t[6];
    158         num[4] = t[7];
    159         tag = 2;
    160         l = arithmetic_fraction(num, s[2], r, tag, e1, k, str);
    161         if (l == -1)return wrong;
    162         num[1] = t[0];
    163         num[2] = t[1];
    164         num[3] = num[5];
    165         num[4] = num[6];
    166         k = 0;
    167         tag = 1;
    168         l = arithmetic_fraction(num, s[0], r, tag, e, k, str);
    169         if (l == -1)return wrong;
    170         e[l] = '\0';
    171         strcat_s(e, e1);
    172     }
    173     if (flag == true) {  //如果是检查文件的运算结果 不用查重
    174         if (repeat(e) == -1)return wrong;
    175         else {
    176             strcpy_s(list[se], 50, e);
    177             se++;
    178         }
    179     }
    180 
    181     printf("%d. ", i + 1);  //打印序号
    182     printf("%s", e);  //打印题目
    183     digit_integer(i + 1, c, x);
    184     strcat_s(c, ".  ");  //序号拼接
    185 
    186     //打印结果
    187     if (str[0] == 0 && str[1] == 0) {
    188         digit_integer(0, a, m);
    189         printf(" = 0\n");
    190     }
    191     else if (str[0] != 0 && str[1] == 0) {
    192         digit_integer(str[0], a, m);
    193         printf(" = %d\n", str[0]);
    194     }
    195     else if (str[0] == 0 && str[1] != 0) {
    196         digit_integer(str[1], a, m);
    197         a[m++] = '/';
    198         digit_integer(str[2], a, m);
    199         printf(" = %d/%d\n", str[1], str[2]);
    200     }
    201     else {
    202         digit_integer(str[0], a, m);
    203         a[m++] = 39;//39是'的ASCII码
    204         digit_integer(str[1], a, m);
    205         a[m++] = '/';
    206         digit_integer(str[2], a, m);
    207         printf(" = %d'%d/%d\n", str[0], str[1], str[2]);
    208     }
    209 
    210     fputs(c, fp1);
    211     fputs(c, fp2);  //写入序号
    212     fputs(e, fp1);  //写入题目
    213     fputs(a, fp2);  //写入答案
    214     fputc('\n', fp1);
    215     fputc('\n', fp2);
    216 
    217     return a;
    218 }
     1 //运算数的加减乘除函数
     2 int arithmetic_fraction(int num[], char sign, int r, int& tag, char e[], int& k, int str[]) {
     3     int x = 0;
     4 
     5     if (sign == '-') {
     6         //对减的情况做判断,减数小于被减数则返回-1,不打印该式子
     7         if (num[1] * num[4] - num[2] * num[3] < 0)  return -1;
     8     }
     9 
    10     //被除数为0则返回-1,不打印该式子
    11     if (sign == '/' && num[3] == 0)  return -1;
    12 
    13     //第一个运算数
    14     if (tag == 1)  division_integer(num[1], num[2], tag, e, k, str);
    15     tag = 2;
    16     signstrcat(sign, e, k);
    17     x = k;
    18     //第二个运算数
    19     division_integer(num[3], num[4], tag, e, k, str);
    20 
    21     //运算过程
    22     if (sign == '+') {
    23         num[5] = num[1] * num[4] + num[3] * num[2];
    24         num[6] = num[2] * num[4];
    25         tag = 3;
    26         division_integer(num[5], num[6], tag, e, k, str);
    27     }
    28     else if (sign == '-') {
    29         num[5] = num[1] * num[4] - num[3] * num[2];
    30         num[6] = num[2] * num[4];
    31         tag = 3;
    32         division_integer(num[5], num[6], tag, e, k, str);
    33     }
    34     else if (sign == '*') {
    35         num[5] = num[1] * num[3];
    36         num[6] = num[2] * num[4];
    37         tag = 3;
    38         division_integer(num[5], num[6], tag, e, k, str);
    39     }
    40     else if (sign == '/') {
    41         num[5] = num[1] * num[4];
    42         num[6] = num[2] * num[3];
    43         tag = 3;
    44         division_integer(num[5], num[6], tag, e, k, str);
    45     }
    46     return x;
    47 }
     1 //整数除法的函数(判断分数是真分数、假分数、整数、0,并化简打印式子)
     2 char division_integer(int& numA, int& numB, int tag, char e[], int& k, int str[]) {
     3     //余数和倍数
     4     int multiple = 0, remainder = 0;
     5     int* p1 = &multiple, * p2 = &remainder;
     6     //最大公因数
     7     int max = max_common(numA, numB);
     8 
     9     //tag=1为第一个运算数,tag=2为其他运算数,tag=3为答案
    10     //被除数为0,除法不存在
    11     if (numB == 0)  return -1;
    12     //分子为0或分母为1
    13     else if (numA == 0 || numB == 1) {
    14         if (tag == 1) {
    15             digit_integer(numA, e, k);
    16         }
    17         else if (tag == 2) {
    18             digit_integer(numA / numB, e, k);
    19         }
    20         else if (tag == 3) {
    21             if (numA == 0) {
    22                 str[0] = 0;
    23                 str[1] = 0;
    24             }
    25             else {
    26                 str[0] = numA;
    27                 str[1] = 0;
    28             }
    29         }
    30         return 0;
    31     }
    32     //判断余数,能整除则返回除法答案
    33     else if (numA % numB == 0) {
    34         if (tag == 1) {
    35             digit_integer(numA / numB, e, k);
    36         }
    37         else if (tag == 2) {
    38             digit_integer(numA / numB, e, k);
    39         }
    40         else if (tag == 3) {
    41             str[0] = numA / numB; str[1] = 0;
    42         }
    43         return numA / numB;
    44     }
    45     //分子大于分母,是假分数,先化简再化为带分数,返回1
    46     else if (numA > numB) {
    47         //最大公因数为1,无需化简
    48         if (max != 1) {
    49             numA = numA / max;
    50             numB = numB / max;
    51         }
    52         change(numA, numB, p1, p2);
    53         if (tag == 1) {
    54             digit_integer(*p1, e, k);
    55             e[k++] = 39;
    56             digit_integer(*p2, e, k);
    57             e[k++] = '/';
    58             digit_integer(numB, e, k);
    59         }
    60         else if (tag == 2) {
    61             digit_integer(*p1, e, k);
    62             e[k++] = 39;
    63             digit_integer(*p2, e, k);
    64             e[k++] = '/';
    65             digit_integer(numB, e, k);
    66         }
    67         else if (tag == 3) {
    68             str[0] = *p1; str[1] = *p2; str[2] = numB;
    69         }
    70         return 1;
    71     }
    72     //分子小于分母,是真分数,只需要化简,返回2
    73     else if (numA < numB) {
    74         //最大公因数为1
    75         if (max != 1) {
    76             numA = numA / max;
    77             numB = numB / max;
    78         }
    79         if (tag == 1) {
    80             digit_integer(numA, e, k);
    81             e[k++] = '/';
    82             digit_integer(numB, e, k);
    83         }
    84         else if (tag == 2) {
    85             digit_integer(numA, e, k);
    86             e[k++] = '/';
    87             digit_integer(numB, e, k);
    88         }
    89         else if (tag == 3) {
    90             str[0] = 0; str[1] = numA; str[2] = numB;
    91         }
    92         return 2;
    93     }
    94 }

    七、测试运行

    未输入某些参数,程序会报错,并给出帮助信息

    按要求输入参数后,程序会打印题目,并将题目和答案分别存入文件。

    生成10道题

     生成100道题

    生成1000道题

    生成10000道题(附文件图)

       

     

    程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。

    给定10道题(附文件图)

        

    10道题中修改1、5、8题的答案

          

    判定结果如下

           

    八、项目小结

    总结教训

    1. 要在写项目之前构造好整体框架思路。本次项目的开发,中途出现了多次前后思路冲突,导致产生了一些很难找到的bug,花费了很多的时间。

    2. 本次采用了C语言开发此项目,感觉较为繁琐,但两人对C语言都较为熟悉,在开发过程中还算顺利。

    3. 本项目中的查重需求,两人讨论了很久并且上网查询了相关资料,但没有拿出一个很好的、较简化的思路和方案。加之一开始做的时候并没有想到用相关的存储结构存储数据,导致在后边想实现查重需求就变得非常繁琐,再重复用存储结构存储时非常不便,所以并未完整实现该需求。

    4. 在整个开发过程中,要及时和队友交流想法和成果,以确保能够互相配合编写代码完成项目。

    结对情况

    本次结对项目使用github管理代码,两人各开一个分支,在完成相应的功能后将自己的分支合并到master分支,供队友获取最新代码。

        

    结对感受

    1. 遇到问题,能和队友讨论,在讨论的过程中两人互相提出质疑和建议,感受比百度好用多了!

    2. 通过结对,学习到了队友身上的一些思路和经验,感觉更好的完善了自己的开发思路和框架。

    3. 当自己写的代码找不到bug出处时,和队友一起研究讨论是个很好的解决方法。

     

    闪光点/建议/分享

    To 芯悦:

      经常会对自己写的代码做化简,也会对我的代码提出建议,来简化整个项目的开发。这种思考值得我多加学习和总结。

    To 晓莹:

      很有耐心,遇到问题会认真琢磨。经常会和我分享讨论想法来解决问题,在整个项目开发过程中帮助了我很多。

     

     

  • 相关阅读:
    windows系统下强制杀死某个进程
    onenote快捷键
    sublime封装代码块快捷键、eemet插件安装、Loading PyV8 binary...的解决办法
    google浏览器截长图的方法
    (转)Java基础加强之并发(二)常用的多线程实现方式
    hibernate学习(初识)
    Spring中的事务操作
    JDBC最原始的代码做查询操作
    Spring的JDBC模板
    Spring AOP
  • 原文地址:https://www.cnblogs.com/pipiying/p/12609757.html
Copyright © 2011-2022 走看看