• 佛系结对编程---四则运算(Core 第四组)


    ----by core 第四组 ( 邹卫其 范力 )

    一. 项目介绍

    1. 能自动生成小学四则运算题目并给出答案,生成题目时可以选择下列参数:

       1)生成题目数量

       2)每道题目中运算数数量

       3)运算数数值范围

       4)运算符种类(  +  -  *  /  ^  )

       5)运算数类型(整数,小数,分数)

       6)运算数精度(保留到小数点后几位)

    2. 将四则运算的计算功能包装在一个模块中( class 或 DLL)

    3. 将 core 模块通过一定的 API 接口 (Application Programming Interface) 来和 UI 组对接

    4. UI 组测试所有 core 组 DLL 后,core 组需根据 UI 组的测试结果进行反馈优化

    5. 项目管理和撰写博客

    6. 项目 Github 地址:https://github.com/eudaem/homework2/pull/2

     

    二. 功能分析

     

    1. 创建 class Node 类, 储存数据信息,所有操作数值以分数存储;以 Node 类为节点建立二叉树存储表达式所有信息。

    2. 算术表达式树的树枝天然是运算符,树叶是操作数;先随机生成运算符树,再将树叶补全即可。

    3. 在用户选择乘方时我们将 '^' 运算符沉到运算符树底,保证算术表达式不会过于复杂。

    4. 对 Node 类重载加、减、乘、除、乘方运算,重载中所有运算均以分数运算完成。

    5. 递归计算表达式树的值,递归检测到负数时交换左右子树,保证运算过程不出现负数。

    6. 递归生成中缀表达式,并合理地加上括号,以 string 类存储。

    7. 封装大类 Core,创建对象 cal,通过成员函数设置相关参数 , 生成的题目和答案以 string 串的形式传递。

     

     三. 代码实现

     

    1. 定义 Core 类(封装成大类)

     1 class Core
     2 {
     3 private:
     4     int que_num = 100;  //题目数量
     5     int data_num = 10;  //操作数数量
     6     int range = 5;      //计算的数值范围 
     7     int opr_type = 3;   //操作符种类  0.加减  1.加减乘  2.加减乘除  3.加减乘除乘方 
     8     int data_type = 1;  //0整数  1小数  2分数
     9     int accuracy = 2;
    10     string* que = new string[que_num + 1];
    11     string* ans = new string[que_num + 1];
    12 public:
    13     void set_que_num(int a) { que_num = a; }
    14     void set_data_num(int a) { data_num = a; }
    15     void set_range(int a) { range = a; }
    16     void set_opr_type(int a) { opr_type = a; }
    17     void set_data_type(int a) { data_type = a; }
    18     void set_accuracy(int a) { accuracy = a; }
    19     int get_que_num() { return que_num; }
    20     int get_data_num() { return data_num; }
    21     int get_range() { return range; }
    22     int get_opr_type() { return opr_type; }
    23     int get_data_type() { return data_type; }
    24     int get_accuracy() { return accuracy; }
    25     string *getQue();
    26     string *getAns();
    27 private:
    28     string expstring(Node *root);
    29     Node *creatOptree();
    30     Node calc(Node *root);
    31     void previsite(Node *head);    
    32     char operat();
    33     char int_operat();
    34     int get_factor(int a);
    35 };
    View Code

    2. 设置类的参数并调用示例

     1 int main()
     2 {
     3     Core cal;
     4     string *q, *a;
     5 
     6     cal.set_data_num(10);
     7     cal.set_que_num(100);
     8     cal.set_range(10);
     9     cal.set_opr_type(3);
    10     cal.set_data_type(1);
    11     cal.set_accuracy(3);
    12 
    13     q = cal.getQue();
    14     a = cal.getAns();
    15     for (int i = 1; i <= cal.get_que_num(); i++)
    16     {
    17         cout << q[i] <<  " = " << a[i] << endl << endl;
    18     }
    19 
    20     system("pause");
    21     return 0;
    22 }
    View Code

    3. 定义节点 Node 类

     1 class Node
     2 {
     3 public:
     4     Node() { top = -1; bottom = -1; operat = 0; left = NULL; right = NULL; }
     5     Node(int t, int b, char opr) { top = t; bottom = b; operat = opr; left = NULL; right = NULL; }
     6     void simp();
     7     int gcd(int p, int q);
     8     Node operator + (Node n2);
     9     Node operator - (Node n2);
    10     Node operator * (Node n2);
    11     Node operator / (Node n2);
    12     Node operator ^ (Node n2);
    13     Node operator = (Node n2);
    14     
    15 public:
    16     int top;
    17     int bottom;
    18     char operat;
    19     class Node *left;
    20     class Node *right;
    21     
    22 };
    23 
    24 Node Node::operator + (Node n2)
    25 {
    26     Node n;
    27     n.top = top*n2.bottom + bottom*n2.top;
    28     n.bottom = bottom*n2.bottom;
    29     n.operat = 0;
    30     n.left = NULL;
    31     n.right = NULL;
    32     n.simp();
    33     return n;
    34 }
    35 Node Node::operator - (Node n2)
    36 {
    37     Node n;
    38     n.top = top*n2.bottom - bottom*n2.top;
    39     n.bottom = bottom*n2.bottom;
    40     n.operat = 0;
    41     n.left = NULL;
    42     n.right = NULL;
    43     n.simp();
    44     return n;
    45 }
    46 Node Node::operator * (Node n2)
    47 {
    48     Node n;
    49     n.top = top*n2.top;
    50     n.bottom = bottom*n2.bottom;
    51     n.operat = 0;
    52     n.left = NULL;
    53     n.right = NULL;
    54     n.simp();
    55     return n;
    56 }
    57 Node Node::operator / (Node n2)
    58 {
    59     Node n;
    60     n.top = top*n2.bottom;
    61     n.bottom = bottom*n2.top;
    62     n.operat = 0;
    63     n.left = NULL;
    64     n.right = NULL;
    65     n.simp();
    66     return n;
    67 }
    68 Node Node::operator ^ (Node n2)
    69 {
    70     Node n;
    71     n.top = (int)pow(top, n2.top);
    72     n.bottom = (int)pow(bottom, n2.top);
    73     n.operat = 0;
    74     n.left = NULL;
    75     n.right = NULL;
    76     n.simp();
    77 
    78     return n;
    79 }
    80 Node Node::operator = (Node n2)
    81 {
    82     top = n2.top;
    83     bottom = n2.bottom;
    84     operat = n2.operat;
    85     return Node(n2.top, n2.bottom, 0);
    86 }
    View Code

    4. 随机生成一颗算数表达式树

      1 Node* Core::creatOptree()
      2 {
      3     Node *head = NULL, *p = NULL, *q = NULL;
      4     int i = 0, j = 0;
      5     head = new Node;
      6     head->operat = '+';
      7 
      8     for (i = 1, j = 0; i < data_num - 1; i++)
      9     {
     10         p = head;
     11         while (p)
     12         {
     13             if (rand() % 2) {
     14                 if (p->left)  p = p->left;
     15                 else {
     16                     q = new Node;
     17                     if (data_type == 0) q->operat = int_operat();
     18                     else   q->operat = operat();
     19                     p->left = q;
     20                     break;
     21                 }
     22             }
     23             else {
     24                 if (p->right)  p = p->right;
     25                 else {
     26                     q = new Node;
     27                     if (data_type == 0) q->operat = int_operat();
     28                     else   q->operat = operat();
     29                     p->right = q;
     30                     break;
     31                 }
     32             }
     33         }//end while
     34     }//end if
     35     return head;
     36 }
     37 
     38 void Core::previsite(Node *head)
     39 {
     40     if (!head) return;
     41     class Node *q = NULL, *p = NULL;
     42     if (head->operat && opr_type == 3 && !head->left && !head->right)
     43     {
     44         int temp = 0;
     45         temp = rand() % 4;
     46         if (temp == 0) head->operat = '^';
     47     }
     48 
     49     if (head->operat  && data_type == 0 && (opr_type == 2 || opr_type == 3) && !head->left && !head->right)
     50     {
     51         int temp = 0;
     52         temp = rand() % 4;
     53         if (temp == 0) head->operat = '/';
     54     }
     55 
     56     if (head->operat && !head->left)
     57     {
     58         p = new Node;
     59         //reset(q);
     60         p->bottom = rand() % range + 1;
     61         p->top = rand() % range + 1;
     62         if (data_type == 0)  p->bottom = 1; //整数
     63         if (data_type == 0 && head->operat == '/')  p->top = rand() % range + 1;
     64         if (data_type == 1)     //小数
     65         {
     66             p->bottom = 20;
     67             p->top = rand() % (20 * range);
     68         }
     69         if (head->operat == '^')
     70         {
     71             int min = (range < 6) ? range : 6;
     72             p->bottom = 1;
     73             p->top = rand() % min + 1;
     74         }
     75         head->left = p;
     76     }
     77     if (head->operat && !head->right)
     78     {
     79         q = new Node;
     80         //reset(q);
     81         q->bottom = rand() % range + 1;
     82         q->top = rand() % range + 1;
     83         if (data_type == 0) q->bottom = 1;  //整数
     84         if (data_type == 0 && head->operat == '/')  q->top = get_factor(head->left->top);
     85         if (data_type == 1)  //小数
     86         {
     87             q->bottom = 20;
     88             q->top = rand() % (20 * range);
     89         }
     90         if (head->operat == '^')   //乘方
     91         {
     92             int min = (range <= 5) ? range : 5;
     93             q->bottom = 1;
     94             q->top = rand() % min + 1;
     95         }
     96         head->right = q;
     97     }
     98     previsite(head->left);
     99     previsite(head->right);
    100 
    101 }
    View Code

    5. 计算表达式树数值 

     1 Node Core:: calc(Node *root)   //计算树的值
     2 {
     3     Node answer;
     4     if (root == NULL)
     5         return answer;
     6     char opr = root->operat;
     7 
     8     if (opr == 0)
     9     {
    10         return *root;
    11     }
    12     else if (opr == '+')
    13     {
    14         return calc(root->left) + calc(root->right);
    15     }
    16     else if (opr == '-')
    17     {
    18         answer = (calc(root->left) - calc(root->right));
    19         if (answer.top < 0)
    20         {
    21             Node *temp = root->left;
    22             root->left = root->right;
    23             root->right = temp;
    24             answer.top *= -1;
    25         }
    26         return answer;
    27     }
    28     else if (opr == '*')
    29     {
    30         return calc(root->left) * calc(root->right);
    31     }
    32 
    33     else if (opr == '/')
    34     {
    35         if (data_type == 0)
    36         {
    37 
    38         }
    39         return calc(root->left) / calc(root->right);
    40     }
    41 
    42     else if (opr == '^')
    43     {
    44         return calc(root->left) ^ calc(root->right);
    45     }
    46     else
    47         return answer;
    48 }
    View Code

    6. 打印中缀表达式

     1 string Core::expstring(Node *root)  //生成中缀表达式  分子分母间用 | 
     2 {
     3     if (root == NULL)
     4         return que[0];
     5     if (root->left)
     6     {
     7         if ((root->left->operat == '+' || root->left->operat == '-') && (root->operat == '*' || root->operat == '/'))
     8         {
     9             que[0] += "( ";
    10             expstring(root->left);
    11             que[0] += ") ";
    12         }
    13         else if (root->operat == '^' && root->left->operat)
    14         {
    15             que[0] += "( ";
    16             expstring(root->left);
    17             que[0] += ") ";
    18         }
    19         else
    20             expstring(root->left);
    21     }
    22 
    23     if (root->operat == 0)
    24     {
    25         if (data_type == 1)
    26         {
    27             double t = 1.0 * root->top / root->bottom;
    28             stringstream s1;
    29             s1 << t;
    30             que[0] += s1.str();
    31             que[0] += " ";
    32         }
    33         else
    34         {
    35             stringstream s2;
    36             s2 << root->top;
    37             que[0] += s2.str();
    38             if (root->bottom > 1)
    39             {
    40                 que[0] += "|";
    41                 stringstream s3;
    42                 s3 << root->bottom;
    43                 que[0] += s3.str();
    44             }
    45             que[0] += " ";
    46         }
    47     }
    48     else
    49     {
    50         que[0] += root->operat;
    51         que[0] += " ";
    52     }
    53 
    54     if (root->right)
    55     {
    56         if ((root->operat == '-' || root->operat == '*') && (root->right->operat == '-' || root->right->operat == '+'))
    57         {
    58             que[0] += "( ";
    59             expstring(root->right);
    60             que[0] += ") ";
    61         }
    62         else if (root->operat == '/' && (root->right->operat && root->right->operat != '^'))
    63         {
    64             que[0] += "( ";
    65             expstring(root->right);
    66             que[0] += ") ";
    67         }
    68         else if (root->operat == '^'&& root->right->operat)
    69         {
    70             que[0] += "( ";
    71             expstring(root->right);
    72             que[0] += ") ";
    73         }
    74         else
    75             expstring(root->right);
    76     }
    77     return que[0];
    78 }
    View Code

    7. 生成题目 string 数组

     1 string* Core::getQue()
     2 {
     3     Node *head, result;
     4     que = new string[que_num + 1];
     5     ans = new string[que_num + 1];
     6     for (int i = 1; i <= que_num; i++)
     7     {
     8         head = creatOptree();
     9         previsite(head);
    10         result = calc(head);
    11         result.simp();
    12         if (result.bottom == 0 || result.top < 0)
    13             i--;
    14         else
    15         {
    16             que[0] = "";
    17             que[i] = expstring(head);
    18             if (data_type == 1)
    19             {
    20                 double t = 1.0 * result.top / result.bottom;
    21                 stringstream s1;
    22                 s1 << t;
    23                 ans[i] += s1.str();
    24             }
    25             else
    26             {
    27                 stringstream s2;
    28                 s2 << result.top;
    29                 ans[i] += s2.str();
    30                 if (result.bottom > 1)
    31                 {
    32                     ans[i] += "|";
    33                     stringstream s3;
    34                     s3 << result.bottom;
    35                     ans[i] += s3.str();
    36                 }
    37             }
    38         }
    39     }
    40     return que;
    41 }
    View Code

    8. 生成答案 string 数组

     1 string* Core::getAns()
     2 {
     3     if (data_type == 1)
     4     {
     5         for (int i = 1; i <= que_num; i++)
     6         {
     7             for (int j = 0; ans[i][j]; j++)
     8                 if (ans[i][j] == '.')
     9                 {
    10                     for (size_t k = j + accuracy + 1; k < ans[i].length(); k++)
    11                         ans[i][k] = '';
    12                     break;
    13                 }
    14         }
    15     }
    16     return ans;
    17 }
    View Code

    四. 测试

    以下测试样例约定生成 20 道题目,每题 10 个运算数,数值范围 0~10,在加、减、乘、除、乘方模式。

    1. 整数

     1 ( 3 - 8 / 4 ) * ( 10 + 1 ^ 3 ) + 4 ^ 4 - ( 2 + 4 )
     2  = 261
     3 5 / 1 + 1 - 5 + 9 * 10 - ( 10 + 5 - 4 * 2 )
     4  = 84
     5 ( 6 - 4 + 8 ) * ( 10 - ( 5 ^ 1 - 2 ) ) + 5 + 9 + 3
     6  = 87
     7 5 * ( 10 * 7 - 7 ) - 2 / 1 + 9 + 4 ^ 4 + 4
     8  = 582
     9 9 * 3 ^ 2 + 4 * 3 + 7 * ( 9 + ( 10 - 7 ) * 2 )
    10  = 198
    11 6 * ( 6 * 9 - 5 ) * 9 + ( 8 * 10 + 8 - 4 ) * 10
    12  = 3486
    13 ( 2 + 7 ) * ( 6 - 4 ) + ( 10 / 5 + 10 - 4 ) * 9 * 6
    14  = 450
    15 ( 3 + 4 * 4 ) * 4 + 1 ^ 1 * ( 7 / 1 + 1 / 1 )
    16  = 84
    17 10 - 7 / 1 - ( 9 - 8 ) + 4 ^ 5 * ( 8 - 3 / 1 )
    18  = 5122
    19 1 * 5 - 1 - 9 / 3 + 2 / 1 * 4 * 1 ^ 3
    20  = 9
    21 3 / 1 + 10 + 3 / 1 + 2 * 10 + 4 - ( 8 + 6 )
    22  = 26
    23 3 * 2 * ( 4 / 2 + 5 ) + 3 - ( 6 - 3 ) + 9 - 1
    24  = 50
    25 2 * ( 8 - 4 + 1 ) + 1 ^ 5 + 3 + 8 * 4 - 7
    26  = 39
    27 7 + 10 - 4 - 2 + ( 10 + 6 ) * ( 1 ^ 3 + 4 / 2 )
    28  = 59
    29 ( 1 + 9 - 7 / 1 ) * 9 * 10 + 7 * 6 * ( 6 - 2 )
    30  = 438
    31 2 * ( 7 - 2 ) - ( 5 - 9 / 3 ) + 1 * 5 * 3 * 3
    32  = 53
    33 9 + 4 + 2 / 1 * 4 / 2 + 2 * 9 - 9 / 3
    34  = 32
    35 ( 2 ^ 4 + 7 / 1 ) * ( 2 + 9 * 9 ) + 2 * ( 4 + 4 )
    36  = 1925
    37 ( 5 + 4 ^ 1 ) * 2 ^ 4 * 4 + 3 + 8 + 5 / 1
    38  = 592
    39 9 * 9 / 3 + ( 8 + 3 + 9 ) * ( 3 / 1 - 10 / 5 )
    40  = 47
    View string

    2. 小数(精度为 3)

     1 ( 1.05 - 1 ^ 3 ) / ( 1.75 * ( 6.1 - 3.2 ) ) + 3.4 + 3.1 + 6.15 + 8.9
     2  = 21.559
     3 ( 6.85 + 4.1 ) * 7.2 + 1.65 / ( 6 ^ 5 * 2.9 + 1.45 + 5.6 + 8.05 )
     4  = 78.840
     5 ( 9.55 / ( 7.95 - 7.4 ) - 0.65 ) / 7.3 + ( 0.1 + 1.8 ) / ( 9.8 - 3.4 / 6.7 )
     6  = 2.494
     7 1.2 / ( 6.15 + 5.15 - 9.75 - 0.45 ) + 2.9 / ( 9.9 / 9.9 ) * 1.1 / 1.9
     8  = 2.769
     9 ( 3.8 - 1.05 ) * 3.75 / 2 ^ 5 + ( 9.25 + 4.4 ) * 7.85 * 6 ^ 4
    10  = 138870
    11 ( 4.1 / ( 5.05 * 9.3 ) + 9.25 - 0.4 ) * 2 ^ 2 + 1.1 - ( 2.5 - 2.2 )
    12  = 36.549
    13 3.7 + 6 ^ 4 + 9.6 * 4 + ( 8.6 - 7.15 - 0.1 ) * ( 1.6 + 6.25 )
    14  = 1348.7
    15 4.7 + 8.55 + 3.2 - 2.55 + ( 4.35 - 0.5 ) * ( 5.75 + ( 4.1 + 4.35 ) / 2.15 )
    16  = 51.168
    17 ( 2 ^ 5 - 7.65 ) * 2 ^ 4 + 7.85 / 5.4 / ( 0.05 * 9.65 * 7 )
    18  = 390.03
    19 7.95 - 6.45 + 1 ^ 3 + 8.15 * 5.55 + ( 3.75 + 7.1 ) / ( 8.75 - 1.05 )
    20  = 49.141
    21 3 ^ 4 - 0.55 / 3.9 + 6.6 / 1 ^ 3 * ( 7 + 6.75 ) / 7.25
    22  = 93.376
    23 ( 2 ^ 4 - 0.05 ) / ( 3.15 - 0.2 ) + 8.55 - 8.2 + 1.6 * 8.75 + 5.65
    24  = 25.406
    25 3.6 / ( ( 8.45 - 1.15 ) / 8.5 + 1.4 * ( 7.15 - 3.15 ) ) + ( 1.05 + 4.4 ) * 9.4
    26  = 51.787
    27 ( 1.25 + 7.45 ) / ( 3 ^ 2 / 2 ^ 2 ) + 5 ^ 5 * 5 ^ 1
    28  = 15628.9
    29 5 ^ 5 - ( 4.45 + 2.65 + 2.15 ) + 0.1 * ( 8.45 - ( 9.6 - 7.25 ) * 0.4 )
    30  = 3116.5
    31 2 ^ 1 + 5.5 - ( 4.1 - 1.95 ) + ( 7.05 - 4.45 ) * 9.4 - ( 1.4 - 0 )
    32  = 28.39
    33 4 ^ 3 - 8.2 - ( 3.3 - 0.8 ) + 6.55 * 5.9 * 7.05 / ( 4.05 - 1.5 )
    34  = 160.142
    35 3.3 + 9.8 / 7.9 + 2.9 * 4.9 + 9.6 - ( 3.9 + 2.4 ) * 8.75 / 6.8
    36  = 20.243
    37 4.45 - ( 9.25 + 0.75 - ( 4.65 + 5 ) ) + ( 8.95 + 9.1 ) * 1.3 - 8.05 / 7.9
    38  = 26.546
    39 8.1 / 0.75 / 3 ^ 1 + ( 8.35 - 6.6 ) * 2 ^ 4 / 5 ^ 2
    40  = 4.72
    View string

    3. 分数

     1 ( 3|3 - 9|7 / 8|6 ) / ( 2|7 * ( 10|8 - 3|10 ) ) + 4|5 + 3|2 + 5|4 + 2|2
     2  = 1779|380
     3 2|7 * 9|4 / 1|10 + 5|4 * 7|5 + 7 / ( 1 ^ 4 + 9|9 + 10|3 )
     4  = 1063|112
     5 2 - 7|5 - ( 3|2 - 5|6 ) * 6|7 + ( 8|8 - 2|8 ) * 8|8 * ( 6|4 - 10|10 )
     6  = 113|280
     7 7 * ( 10|9 - 5|9 ) + ( 9|10 - 1|9 ) * 5|2 - ( 9|8 + 4|9 * 2|8 ) * 8|9
     8  = 1543|324
     9 9|4 / 9 * ( 9|10 - 8|10 ) / 9|7 / 1|9 + 3|3 - 3|9 / ( 9|8 - 1|10 )
    10  = 4181|4920
    11 ( 10|3 - 7|8 ) / ( 1|3 * 4 ) + 9|2 + 10|2 + ( 3|4 - 3|6 ) * ( 8|8 - 7|9 )
    12  = 3283|288
    13 ( 8|10 + 10|7 - ( 8|6 - 7|7 ) ) * ( 5|6 + 2|5 + 9|6 ) + 4|4 / 6|6 + 2|7
    14  = 10184|1575
    15 4|10 + 6 ^ 4 + 9|3 * 8|9 + 2|9 + 6|3 + 5|5 + 3|5 - 5|8
    16  = 93763|72
    17 3|3 + 8 - 5|7 - 2|6 - ( 3|4 - 4|6 ) + 4|6 * 1|2 * 1|5 / 4
    18  = 276|35
    19 1 ^ 1 * 8|7 * 9|4 + 5 ^ 3 / ( ( 8|6 + 9|10 ) / ( 3 * 4|3 ) )
    20  = 106206|469
    21 ( 4 - 9|9 ) / ( 9 * 4|10 + 8|6 ) + 4 ^ 3 - 1|2 * 1 ^ 2
    22  = 2372|37
    23 10|4 - 6|10 - ( 7|3 - 4|6 ) + ( 5|5 - 3|5 ) / ( ( 3|10 + 8|4 ) * ( 6|2 - 9|8 ) )
    24  = 15|46
    25 6|7 * ( 4 - 2|9 ) / ( 6|6 * 3|3 ) * 5|8 * 3|9 + 7|4 * ( 4 - 3|6 )
    26  = 3427|504
    27 2|5 + 10|4 + 10|8 - 3|9 + 6 ^ 1 + ( 8|2 - 4|4 * 5|3 ) * 5|4
    28  = 191|15
    29 1 ^ 5 + 2|4 + 3 ^ 1 * 8|9 + 3|4 + 7|3 * 3|10 / 6|10
    30  = 73|12
    31 1 ^ 5 + 10|4 - ( 3|9 - 1|9 ) + ( 10 - 7|9 ) / 9|2 * ( 1 + 8|9 )
    32  = 10423|1458
    33 5|6 * ( 4|6 + 7|3 ) * ( 4|7 / 5|10 - 3|9 ) + 7|6 / 2|7 * 6|3 / 7|6
    34  = 379|42
    35 5|4 / 5|4 * 7|4 * 2 ^ 1 + 9 * ( 6 / 5|2 + 4|7 - 3|10 )
    36  = 964|35
    37 9|10 + 2 + 10|6 - 8|9 / ( 2|9 * 4|10 + 2 ) + 6|6 / 10 * 8|5
    38  = 30323|7050
    39 4 / ( 5|9 - 1|9 ) / ( 5|6 + 4|2 ) + 4|8 + 10|9 + 7|4 - ( 6|9 + 10|7 )
    40  = 19031|4284
    View string

    4. 样例分析

    可以看到,我们生成的算数表达式符合参数要求,结构均匀而随机,括号匹配无误,计算结果正确。

    五. DLL 封装和对接

    参考网上知识,采用 VS2017 创建 DLL 文件,在 .h 头文件中进行类的定义和相关声明,在 .cpp 文件中进行各种成员函数的定义。在完成 DLL 相关配置后,生成新的解决方案,生成相应的 .lib 和 .dll 文件。

    编写测试程序,测试 DLL 文件,将 .h .lib 和 .dll 文件复制到相应文件夹,在头文件中引用 .h 文件,在资源文件引用 .lib 文件,在 main 函数中创建对象,引用成员函数,检测成功后给 UI 组初步对接。

    与 UI 组进行 DLL 对接时,其中一组曾编译出现 “LNK2019 无法解析的外部符号” 的报错,后来排查得知是 x64 和 x86 平台差异引起,于是我们对 x86 和 x64 分别生成 .lib 和 .dll 文件,解决了这个问题。

     

    六. 结对编程感悟

    这次结对的过程中 zou 主要完成算术表达式的计算,中缀显示,类的封装,DLL 文件的生成;fan 主要完成算数表达式在各种情况下的生成,API 和博客的撰写。

    这次编程非常佛系最后一天上午才完成,然后忙着和 UI 组对接,总的来说结对编程的效率远高于独立作业,我们将思路理顺之后编程非常高效,出现 bug 之后也能及时发现并解决。

    面对再一次的编程任务,我们抱以一种佛系的心态,一开始并未着急编写,吸取上次经验,讨论了很多种方案,仔细分析优劣,最终理清思路并梳理了整体的框架,有条不紊地编写时并未出现太多意料之外的困难。

    面对问题的处理方式是多种多样的,结对编程优势之一就是,两个人的积极性互相被调动,个人陷入局部困境导致整体目标变模糊的概率也大为减小,与之同时,不论焦急还是从容,死限 DDL 来临的速率是一个常数,所以不妨用更加佛系的心态,减少实际行动中漫无目的或毫无效率忙碌,更多地在思维活跃而清晰之下充分调用自身能力,稳健地去面对。

     

    七. PSP 表格

     

    Personal Software Process Stages预估耗时(分)实际耗时(分)
    计划 10 10
    · 估计这个任务需要多少时间 10 10
    开发 1495 1540
    · 需求分析 (包括学习新技术) 2h * 60 3h * 60
    · 生成设计文档 30 20
    · 设计复审 (和同事审核设计文档) 5 5
    · 代码规范 (为目前的开发制定合适的规范) 10 5
    · 具体设计 30 30
    · 具体编码 12h * 60 10h * 60
    · 代码复审 30 40
    · 测试(自我测试,修改代码,提交修改) 10h * 60 11h * 60
    报告 70 60
    · 测试报告 30 30
    · 计算工作量 10 10
    · 事后总结, 并提出过程改进计划 30 20
      1555 1620

      

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    C#调用java类、jar包方法
    利用IKVM在C#中调Java程序
    同样版本的jstl,都是jstl1.2版本,有个有问题,另一个没有问题
    Python安装及开发环境配置
    jQuery EasyUI parser 的使用场景
    关于HttpURLConnection.setFollowRedirects
    HttpUrlConnection 的 setDoOutput 与 setDoInput
    【Mybatis】向MySql数据库插入千万记录 单条插入方式,用时 1h16m30s
    [MyBatis]再次向MySql一张表插入一千万条数据 批量插入 用时5m24s
    [MyBatis]向MySql数据库插入一千万条数据 批量插入用时6分 之前时隐时现的异常不见了
  • 原文地址:https://www.cnblogs.com/ustcfanli/p/8847037.html
Copyright © 2020-2023  润新知