• 第3次作业


    要求0:作业链接地址 :https://edu.cnblogs.com/campus/nenu/2016CS/homework/2266

    要求1:Git仓库地址为:https://git.coding.net/wudb527/f4.git

    要求2:

    一、结对编程同学姓名为 白银升,博客链接地址为:https://www.cnblogs.com/baiys581/p/9934346.html

    二、作业思路:这次作业是要求随机产生四则运算,但是随机也是要在一定范围内随机。

    1.关于随机数,我用的是cstdlib里面的rand()函数,为了校验方便,我并没有为随机函数设置随机种子,使用的是默认的随机种子,这样的话在用一个机器下执行两次程序的结果相同,有利于验证答案,并且我写了一个在给定范围内生成整形随机数的函数,每次生成[a,b]范围的整数。

    1 int Rand(int a,int b)//生成随机数函数,范围是[a,b]
    2 {
    3     return (rand() % (b-a+1))+ a;
    4 }

    2.关于四则算式,运算符和操作数我都用一个结构体保存,我感觉我比较得意的是我同时保存了每一个操作数或运算符的值、类型和显示时的类型,isnum值为true代表这个Node为一个数,isnum值为false代表这个Node为一个运算符或者括号,name和value代表某个值的显示名称和值,无论是整数还是小数我都用浮点型保存值,比如数字34,那么isnum= true;name = "34";value = 34.0; 如果是运算符'+',那么isnum = false,name = "+";

    1 struct Node//存储每个数
    2 {
    3     bool isnum;
    4     string name;
    5     double value;
    6 };

    写了一个整形转为string类型的函数

     1 string int2str(int t)//整数转化为字符串
     2 {
     3     if(t == 0) return "0";
     4     string str = "";
     5     char ch;
     6     while(t > 0)
     7     {
     8         ch = (t%10 + '0');
     9         str = ch + str;
    10         t /= 10;
    11     }
    12     return str;
    13 }

    所以生成一个整形操作数的代码为:

    1 t = Rand(1,20);
    2 line[i].isnum = true;
    3 line[i].name = int2str(t);
    4 line[i].value = double(t*1.0);

    整个四则算式因为是4个数,3个运算符,所以我定义一个Node类型的数组来保存,功能1的话我使用的长度为7,功能2、3的话我只会产生1对括号,所以使用的长度为9。

    1 Node line[9];

    3.运算符的话的是用一个字符串"+-*/"保存,每次从0~3中随机产生,就能确定一个运算符。

    1 char Operator[] = "+-*/";
    2 line[i].name = Operator[Rand(0,3)];

    4.关于括号的生成,我只考虑了生成1对括号,所以关于1234,4个操作数,括号里的内容有12,13,14,23,24,34--5种情况,所以我随机产生[3,7]范围内的随机数,每一个数代表一种括号产生的形式

    功能2中我是先生成不带括号,然后对于每一种括号形式进行单独构造

     1 for(int i = 0; i < 7; ++i)
     2         {
     3             if(i%2 == 0)
     4                 line1[i] = makeNode();
     5             else
     6             {
     7                 line1[i].isnum = false;
     8                 line1[i].name = Operator[Rand(0,3)];
     9             }
    10         }
    11         int r = Rand(3,7);
    12         if(r == 3)
    13         {
    14             line[0] = t1;
    15             line[4] = t2;
    16             for(int i = 1; i <= 3; ++i)
    17             {
    18                 line[i] = line1[i-1];
    19             }
    20             for(int i = 5; i <= 8; ++i)
    21             {
    22                 line[i] = line1[i-2];
    23             }
    24         }
    25         else if(r == 4)
    26         {
    27             line[0] = t1;
    28             for(int i = 1; i <= 5; ++i)
    29                 line[i] = line1[i-1];
    30             line[6] = t2;
    31             for(int i = 7; i <= 8; ++i)
    32             {
    33                 line[i] = line1[i-2];
    34             }
    35         }
    36         else if(r == 5)
    37         {
    38             for(int i = 0; i <= 1; i++)
    39                 line[i] = line1[i];
    40             line[2] = t1;
    41             for(int i = 3; i <= 5; ++i)
    42                 line[i] = line1[i-1];
    43             line[6] = t2;
    44             for(int i = 7; i <= 8; ++i)
    45                 line[i] = line1[i-2];
    46         }
    47         else if(r == 6)
    48         {
    49             for(int i = 0; i <= 1; i++)
    50                 line[i] = line1[i];
    51             line[2] = t1;
    52             for(int i = 3; i <= 7; ++i)
    53                 line[i] = line1[i-1];
    54             line[8] = t2;
    55         }
    56         else if(r == 7)
    57         {
    58             for(int i = 0; i <= 3; i++)
    59             {
    60                 line[i] = line1[i];
    61             }
    62             line[4] = t1;
    63             for(int i = 5; i <= 7; ++i)
    64                 line[i] = line1[i-1];
    65             line[8] = t2;
    66         }

    5.关于功能2种生成小数,写了一个makenode函数用于功能2中操作数的生成,包括了整数小数的选择,小数的生成,小数范围为1.0~20.9

     1 Node makeNode()
     2 {
     3     Node ans;
     4     int t = Rand(0,1);
     5     if(t == 0)
     6     {
     7         int num = Rand(1,20);
     8         ans.isnum = true;
     9         ans.name = int2str(num);
    10         ans.value = (double)num*1.0;
    11     }
    12     else
    13     {
    14         int t1,t2;
    15         t1 = Rand(1,20);
    16         t2 = Rand(0,9);
    17         ans.isnum = true;
    18         ans.name = int2str(t1)+"."+int2str(t2);
    19         ans.value = double(t1*1.0+t2/10.0);
    20     }
    21     return ans;
    22 }

    6.关于四则表达式的计算,用的是数据结构中的算法,由中缀表达式转化为后缀表达式,也就是逆波兰表达式,再由逆波兰表达式计算出值。我写了一个函数用于以上过程。

    算法的文字描述如下

    一、 将中缀表达式转换成后缀表达式算法:
    1、从左至右扫描一中缀表达式。
    2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
    3、若读取的是运算符
      (1) 该运算符为左括号"(",则直接存入运算符堆栈。
      (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
      (3) 该运算符为非括号运算符:
          (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
          (b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。
          (c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。
    4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
     
    二、逆波兰表达式求值算法:
    1、循环扫描语法单元的项目。
    2、如果扫描的项目是操作数,则将其压入操作数堆栈,并扫描下一个项目。
    3、如果扫描的项目是一个二元运算符,则对栈的顶上两个操作数执行该运算。
    4、如果扫描的项目是一个一元运算符,则对栈的最顶上操作数执行该运算。
    5、将运算结果重新压入堆栈。
    6、重复步骤2-5,堆栈中即为结果值。
      1 double Calculate(int len,bool& havewrong)
      2 {
      3     havewrong = false;
      4     Node t;
      5     while(!numb.empty()) numb.pop();
      6     while(!Opt.empty()) Opt.pop();
         //中缀转为后缀
    7 for(int i = 0; i < len; ++i) 8 { 9 if(line[i].name == "(") 10 { 11 Opt.push(line[i]); 12 } 13 else if(line[i].name == ")") 14 { 15 while(1) 16 { 17 18 t = Opt.top(); 19 Opt.pop(); 20 if(t.name == "(") 21 { 22 break; 23 } 24 else 25 { 26 numb.push(t); 27 } 28 } 29 } 30 else if(line[i].isnum == false) 31 { 32 if(Opt.empty() == true) 33 { 34 Opt.push(line[i]); 35 continue; 36 } 37 38 t = Opt.top(); 39 if(t.name == "(") 40 { 41 Opt.push(line[i]); 42 } 43 else if(opt2int(line[i].name) > opt2int(t.name)) 44 { 45 Opt.push(line[i]); 46 } 47 else if(opt2int(line[i].name) <= opt2int(t.name)) 48 { 49 while(!Opt.empty()) 50 { 51 t = Opt.top(); 52 53 if(opt2int(line[i].name) > opt2int(t.name)) 54 { 55 Opt.push(line[i]); 56 break; 57 } 58 else 59 { 60 numb.push(t); 61 Opt.pop(); 62 } 63 } 64 if(Opt.empty() == true) Opt.push(line[i]); 65 } 66 } 67 else if(line[i].isnum == true) 68 { 69 numb.push(line[i]); 70 } 71 } 72 while(!Opt.empty()) 73 { 74 t = Opt.top(); 75 Opt.pop(); 76 numb.push(t); 77 } 78 while(!numb.empty()) 79 { 80 line[numb.size()-1] = numb.top(); 81 numb.pop(); 82 }
         //计算后缀表达式的值
    83 double ans; 84 Node t1,t2; 85 for(int i = 0; i < 7 ; ++i) 86 { 87 if(line[i].isnum == true) numb.push(line[i]); 88 else if(line[i].isnum == false) 89 { 90 t2 = numb.top(); 91 numb.pop(); 92 t1 = numb.top(); 93 numb.pop(); 94 95 t.isnum = true; 96 if(line[i].name == "+") 97 { 98 t.value = t1.value + t2.value; 99 } 100 else if(line[i].name == "-") 101 { 102 t.value = t1.value - t2.value; 103 } 104 else if(line[i].name == "/") 105 { 106 if(fabs(t2.value) < eps) 107 { 108 havewrong = true; 109 return 0.1; 110 } 111 else 112 t.value = t1.value / t2.value; 113 } 114 else if(line[i].name == "*") 115 { 116 t.value = t1.value * t2.value; 117 } 118 numb.push(t); 119 } 120 } 121 //cout<<"numb.size() = "<<numb.size()<<endl; 122 return (numb.top()).value; 123 }

     7.功能1代码

     1 void Function1(int n)
     2 {
     3     string str_ans = "";
     4     string str_line = "";
     5     string input;
     6     int right = 0;
     7     for(int h = 1; h <= n; ++h)
     8     {
     9         str_line = "";
    10         int t;
    11         for(int i = 0; i<7; i++)
    12         {
    13             if(i%2 == 0)
    14             {
    15                 t = Rand(1,20);
    16                 line[i].isnum = true;
    17                 line[i].name = int2str(t);
    18                 line[i].value = double(t*1.0);
    19             }
    20             else
    21             {
    22                 line[i].isnum = false;
    23                 line[i].name = Operator[Rand(0,3)];
    24             }
    25             str_line += line[i].name;
    26         }
    27         bool havewrong;
    28         double ans = Calculate(7,havewrong);
    29         if(havewrong == true)
    30         {
    31             h--;
    32             continue;
    33         }
    34         else
    35         {
    36             cout<<str_line<<endl;
    37             str_ans = double2str(ans);
    38         }
    39         cin>>input;
    40         if("?" + str_ans == input)
    41         {
    42             puts("回答正确。
    ");
    43             right++;
    44         }
    45         else
    46         {
    47             cout<<"回答错误,正确答案是"<<str_ans<<endl;
    48         }
    49     }
    50     printf("总共%d道题,你答对%d道题。
    ",n,right);
    51 }

    功能2、3,在同一函数内,用func_num区别

      1 void Function2(int n,int func_numb)
      2 {
      3     map<string,bool> Map;
      4     FILE *fp = NULL;
      5     if(func_numb == 3)
      6     {
      7         fp = fopen(file_path.c_str(),"w+");
      8         if(fp == NULL)
      9         {
     10             cout<<"文件打开失败。"<<endl;
     11             return;
     12         }
     13     }
     14     string str_ans = "";
     15     string str_line = "";
     16     string str_input;
     17     int right = 0;
     18 
     19     Node line1[9];
     20     Node t1,t2;
     21 
     22     t1.isnum = false;
     23     t1.name = "(";
     24 
     25     t2.isnum = false;
     26     t2.name = ")";
     27     for(int h = 1; h <= n; h++)
     28     {
     29         str_line = "";
     30         for(int i = 0; i < 7; ++i)
     31         {
     32             if(i%2 == 0)
     33                 line1[i] = makeNode();
     34             else
     35             {
     36                 line1[i].isnum = false;
     37                 line1[i].name = Operator[Rand(0,3)];
     38             }
     39         }
     40         int r = Rand(3,7);
     41         if(r == 3)
     42         {
     43             line[0] = t1;
     44             line[4] = t2;
     45             for(int i = 1; i <= 3; ++i)
     46             {
     47                 line[i] = line1[i-1];
     48             }
     49             for(int i = 5; i <= 8; ++i)
     50             {
     51                 line[i] = line1[i-2];
     52             }
     53         }
     54         else if(r == 4)
     55         {
     56             line[0] = t1;
     57             for(int i = 1; i <= 5; ++i)
     58                 line[i] = line1[i-1];
     59             line[6] = t2;
     60             for(int i = 7; i <= 8; ++i)
     61             {
     62                 line[i] = line1[i-2];
     63             }
     64         }
     65         else if(r == 5)
     66         {
     67             for(int i = 0; i <= 1; i++)
     68                 line[i] = line1[i];
     69             line[2] = t1;
     70             for(int i = 3; i <= 5; ++i)
     71                 line[i] = line1[i-1];
     72             line[6] = t2;
     73             for(int i = 7; i <= 8; ++i)
     74                 line[i] = line1[i-2];
     75         }
     76         else if(r == 6)
     77         {
     78             for(int i = 0; i <= 1; i++)
     79                 line[i] = line1[i];
     80             line[2] = t1;
     81             for(int i = 3; i <= 7; ++i)
     82                 line[i] = line1[i-1];
     83             line[8] = t2;
     84         }
     85         else if(r == 7)
     86         {
     87             for(int i = 0; i <= 3; i++)
     88             {
     89                 line[i] = line1[i];
     90             }
     91             line[4] = t1;
     92             for(int i = 5; i <= 7; ++i)
     93                 line[i] = line1[i-1];
     94             line[8] = t2;
     95         }
     96 
     97         for(int i = 0 ; i < 9; i++)
     98             str_line += line[i].name;
     99         bool havewrong;
    100         double ans = Calculate(9,havewrong);
    101         if(havewrong == true)
    102         {
    103             h--;
    104             continue;
    105         }
    106         else
    107         {
    108             str_ans = double2str(ans);
    109         }
    110         if(Map[str_ans] == true){
    111             h--;
    112             continue;
    113         }
    114         else Map[str_ans] = true;
    115         if(func_numb == 2)
    116         {
    117             cout<<str_line<<endl;
    118             cin>>str_input;
    119             if("?" + str_ans == str_input)
    120             {
    121                 puts("回答正确。
    ");
    122                 right++;
    123             }
    124             else
    125             {
    126                 cout<<"回答错误,正确答案是"<<str_ans<<endl;
    127             }
    128         }
    129         else if(func_numb == 3)
    130         {
    131             printf("%s=",str_line.c_str());
    132             fprintf(fp,"%s=",str_line.c_str());
    133             for(int i = 0;i < 20 - str_line.size();i++)
    134             {
    135                 printf(" ");
    136                 fprintf(fp," ");
    137             }
    138             printf("%s
    ",str_ans.c_str());
    139             fprintf(fp,"%s
    ",str_ans.c_str());
    140 
    141         }
    142     }
    143     fclose(fp);
    144     if(func_numb == 2)
    145     printf("总共%d道题,你答对%d道题。
    ",n,right);
    146 }

     8.队友功能3中重复算式的去除,我是按照去除相同答案的方法,用一个map<string,bool>Map;来保存一个答案是否出现过,如果出现过,将重新进行构造算式、计算等等

    1         map<string,bool> Map;
    2         if(Map[str_ans] == true){
    3             h--;
    4             continue;
    5         }
    6         else Map[str_ans] = true;    

     9.对于除0的避免,在计算过程中,每次遇到 ‘ / ’ 时,判断有边的数是不是0,如果是重新构造算式、计算

     1             else if(line[i].name == "/")
     2             {
     3                 if(fabs(t2.value) < eps)
     4                 {
     5                     havewrong = true;
     6                     return 0.1;
     7                 }
     8                 else
     9                     t.value = t1.value / t2.value;
    10             }

     10.功能3中答案对齐的解决,由于我的算式长处最长不会超过20,所以我在输出完算式后,在输出20 - 当前算式长度  的空格,用于对齐

     1             printf("%s=",str_line.c_str());
     2             fprintf(fp,"%s=",str_line.c_str());
     3             for(int i = 0;i < 20 - str_line.size();i++)
     4             {
     5                 printf(" ");
     6                 fprintf(fp," ");
     7             }
     8             printf("%s
    ",str_ans.c_str());
     9             fprintf(fp,"%s
    ",str_ans.c_str());
    10         

     11.对于运算符的优先级比较,我写了一个函数用于返回运算符的优先级

    1 int opt2int(string str)
    2 {
    3     if(str == "+"|| str == "-") return 1;
    4     if(str == "*"|| str == "/") return 2;
    5 }

     12.对于有效数字的判断,对于一个double类型的数我,我先让他乘1000,再四舍五入为整数,然后除以1000,就等于按照题目要求保留了三位有效数字,比如1.234567变为1234.567,再四舍五入变为整数1235,再变为1.235,就等于四舍五入的保留了3位有效数字,最后我用sstream里面的字符串流转换为字符串,这样既可以去除末尾0,又便利于答案的校验,下面是函数

     1 string double2str(double x)//浮点数转化为字符串
     2 {
     3     string ans;
     4     x = x*1000;
     5     int num = round(x);
     6     x = (double)num*1.0/1000.0;
     7     stringstream ssss;
     8     ssss<<x;
     9     ssss>>ans;
    10     return ans;
    11 }

    功能1演示结果

    功能2

    功能3

     完整代码

    #include<iostream>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<cstdlib>
    #include<stack>
    #include<cstdio>
    #include<map>
    #include<sstream>
    #include<cstdio>
    using namespace std;
    
    const double eps = 1e-7;
    string input[10];
    int is_correct_input()
    {
        int f = 1;
        for(int i = 0; i < input[2].size(); ++i)
        {
            if(input[2][i] >='1' && input[2][i] <= '9') f = 0;
            if(!(input[2][i]>='0'&&input[2][i] <= '9')) return -1;
        }
        if(f == 1 ) return false;
        int ans = 0;
        for(int i = 0; i < input[2].size(); ++i)
        {
            ans = ans*10;
            ans += input[2][i] - '0';
        }
        //if(ans == 0) return -1;
        return ans;
    }
    int Rand(int a,int b)//生成随机数函数,范围是[a,b]
    {
        return (rand() % (b-a+1))+ a;
    }
    char Operator[] = "+-*/";//运算符
    struct Node//存储每个数
    {
        bool isnum;
        string name;
        double value;
    };
    Node line[9];
    
    stack<Node>numb;
    stack<Node>Opt;
    string ans;
    int opt2int(string str)
    {
        if(str == "+"|| str == "-") return 1;
        if(str == "*"|| str == "/") return 2;
    }
    
    double Calculate(int len,bool& havewrong)
    {
        havewrong = false;
        Node t;
        while(!numb.empty()) numb.pop();
        while(!Opt.empty()) Opt.pop();
        for(int i = 0; i < len; ++i)
        {
            if(line[i].name == "(")
            {
                Opt.push(line[i]);
            }
            else if(line[i].name == ")")
            {
                while(1)
                {
    
                    t = Opt.top();
                    Opt.pop();
                    if(t.name == "(")
                    {
                        break;
                    }
                    else
                    {
                        numb.push(t);
                    }
                }
            }
            else if(line[i].isnum == false)
            {
                if(Opt.empty() == true)
                {
                    Opt.push(line[i]);
                    continue;
                }
    
                t = Opt.top();
                if(t.name == "(")
                {
                    Opt.push(line[i]);
                }
                else if(opt2int(line[i].name) > opt2int(t.name))
                {
                    Opt.push(line[i]);
                }
                else if(opt2int(line[i].name) <= opt2int(t.name))
                {
                    while(!Opt.empty())
                    {
                        t = Opt.top();
    
                        if(opt2int(line[i].name) > opt2int(t.name))
                        {
                            Opt.push(line[i]);
                            break;
                        }
                        else
                        {
                            numb.push(t);
                            Opt.pop();
                        }
                    }
                    if(Opt.empty() == true) Opt.push(line[i]);
                }
            }
            else if(line[i].isnum == true)
            {
                numb.push(line[i]);
            }
        }
        while(!Opt.empty())
        {
            t = Opt.top();
            Opt.pop();
            numb.push(t);
        }
        while(!numb.empty())
        {
            line[numb.size()-1] = numb.top();
            numb.pop();
        }
        double ans;
        Node t1,t2;
        for(int i = 0; i < 7 ; ++i)
        {
            if(line[i].isnum == true) numb.push(line[i]);
            else if(line[i].isnum == false)
            {
                t2 = numb.top();
                numb.pop();
                t1 = numb.top();
                numb.pop();
    
                t.isnum = true;
                if(line[i].name == "+")
                {
                    t.value = t1.value + t2.value;
                }
                else if(line[i].name == "-")
                {
                    t.value = t1.value - t2.value;
                }
                else if(line[i].name == "/")
                {
                    if(fabs(t2.value) < eps)
                    {
                        havewrong = true;
                        return 0.1;
                    }
                    else
                        t.value = t1.value / t2.value;
                }
                else if(line[i].name == "*")
                {
                    t.value = t1.value * t2.value;
                }
                numb.push(t);
            }
        }
        //cout<<"numb.size() = "<<numb.size()<<endl;
        return (numb.top()).value;
    }
    
    string int2str(int t)//整数转化为字符串
    {
        if(t == 0) return "0";
        string str = "";
        char ch;
        while(t > 0)
        {
            ch = (t%10 + '0');
            str = ch + str;
            t /= 10;
        }
        return str;
    }
    string double2str(double x)//浮点数转化为字符串
    {
        string ans;
        x = x*1000;
        int num = round(x);
        x = (double)num*1.0/1000.0;
        stringstream ssss;
        ssss<<x;
        ssss>>ans;
        return ans;
    }
    void Function1(int n)
    {
        string str_ans = "";
        string str_line = "";
        string input;
        int right = 0;
        for(int h = 1; h <= n; ++h)
        {
            str_line = "";
            int t;
            for(int i = 0; i<7; i++)
            {
                if(i%2 == 0)
                {
                    t = Rand(1,20);
                    line[i].isnum = true;
                    line[i].name = int2str(t);
                    line[i].value = double(t*1.0);
                }
                else
                {
                    line[i].isnum = false;
                    line[i].name = Operator[Rand(0,3)];
                }
                str_line += line[i].name;
            }
            bool havewrong;
            double ans = Calculate(7,havewrong);
            if(havewrong == true)
            {
                h--;
                continue;
            }
            else
            {
                cout<<str_line<<endl;
                str_ans = double2str(ans);
            }
            cin>>input;
            if("?" + str_ans == input)
            {
                puts("回答正确。
    ");
                right++;
            }
            else
            {
                cout<<"回答错误,正确答案是"<<str_ans<<endl;
            }
        }
        printf("总共%d道题,你答对%d道题。
    ",n,right);
    }
    
    Node makeNode()
    {
        Node ans;
        int t = Rand(0,1);
        if(t == 0)
        {
            int num = Rand(1,20);
            ans.isnum = true;
            ans.name = int2str(num);
            ans.value = (double)num*1.0;
        }
        else
        {
            int t1,t2;
            t1 = Rand(1,20);
            t2 = Rand(0,9);
            ans.isnum = true;
            ans.name = int2str(t1)+"."+int2str(t2);
            ans.value = double(t1*1.0+t2/10.0);
        }
        return ans;
    }
    string file_path;
    void Function2(int n,int func_numb)
    {
        map<string,bool> Map;
        FILE *fp = NULL;
        if(func_numb == 3)
        {
            fp = fopen(file_path.c_str(),"w+");
            if(fp == NULL)
            {
                cout<<"文件打开失败。"<<endl;
                return;
            }
        }
        string str_ans = "";
        string str_line = "";
        string str_input;
        int right = 0;
    
        Node line1[9];
        Node t1,t2;
    
        t1.isnum = false;
        t1.name = "(";
    
        t2.isnum = false;
        t2.name = ")";
        for(int h = 1; h <= n; h++)
        {
            str_line = "";
            for(int i = 0; i < 7; ++i)
            {
                if(i%2 == 0)
                    line1[i] = makeNode();
                else
                {
                    line1[i].isnum = false;
                    line1[i].name = Operator[Rand(0,3)];
                }
            }
            int r = Rand(3,7);
            if(r == 3)
            {
                line[0] = t1;
                line[4] = t2;
                for(int i = 1; i <= 3; ++i)
                {
                    line[i] = line1[i-1];
                }
                for(int i = 5; i <= 8; ++i)
                {
                    line[i] = line1[i-2];
                }
            }
            else if(r == 4)
            {
                line[0] = t1;
                for(int i = 1; i <= 5; ++i)
                    line[i] = line1[i-1];
                line[6] = t2;
                for(int i = 7; i <= 8; ++i)
                {
                    line[i] = line1[i-2];
                }
            }
            else if(r == 5)
            {
                for(int i = 0; i <= 1; i++)
                    line[i] = line1[i];
                line[2] = t1;
                for(int i = 3; i <= 5; ++i)
                    line[i] = line1[i-1];
                line[6] = t2;
                for(int i = 7; i <= 8; ++i)
                    line[i] = line1[i-2];
            }
            else if(r == 6)
            {
                for(int i = 0; i <= 1; i++)
                    line[i] = line1[i];
                line[2] = t1;
                for(int i = 3; i <= 7; ++i)
                    line[i] = line1[i-1];
                line[8] = t2;
            }
            else if(r == 7)
            {
                for(int i = 0; i <= 3; i++)
                {
                    line[i] = line1[i];
                }
                line[4] = t1;
                for(int i = 5; i <= 7; ++i)
                    line[i] = line1[i-1];
                line[8] = t2;
            }
    
            for(int i = 0 ; i < 9; i++)
                str_line += line[i].name;
            bool havewrong;
            double ans = Calculate(9,havewrong);
            if(havewrong == true)
            {
                h--;
                continue;
            }
            else
            {
                str_ans = double2str(ans);
            }
            if(Map[str_ans] == true){
                h--;
                continue;
            }
            else Map[str_ans] = true;
            if(func_numb == 2)
            {
                cout<<str_line<<endl;
                cin>>str_input;
                if("?" + str_ans == str_input)
                {
                    puts("回答正确。
    ");
                    right++;
                }
                else
                {
                    cout<<"回答错误,正确答案是"<<str_ans<<endl;
                }
            }
            else if(func_numb == 3)
            {
                printf("%s=",str_line.c_str());
                fprintf(fp,"%s=",str_line.c_str());
                for(int i = 0;i < 20 - str_line.size();i++)
                {
                    printf(" ");
                    fprintf(fp," ");
                }
                printf("%s
    ",str_ans.c_str());
                fprintf(fp,"%s
    ",str_ans.c_str());
    
            }
        }
        fclose(fp);
        if(func_numb == 2)
        printf("总共%d道题,你答对%d道题。
    ",n,right);
    }
    int main(int argc,char* argv[])
    {
        for(int i = 0; i < argc; ++i)
        {
            input[i] = argv[i];
        }
        if(argc != 3 && argc != 5)
        {
            printf("输入参数数量不正确.
    ");
        }
        else
        {
            int ipt = is_correct_input();
            if(input[1] == "-n")
            {
                if(ipt == -1) cout<<"题目数量必须是 正整数。"<<endl;
                else
                Function1(ipt);
            }
            else if(input[1] == "-c")
            {
                if(ipt == -1) cout<<"题目数量范围为1到100之间的正整数。"<<endl;
                else if(argc == 3)
                {
                    Function2(ipt,2);
                }
                else if(argc == 5)
                {
                    for(int i = 0;i < argc;i++)
                    {
                        if(input[i] == "-f")
                        {
                            file_path = "";
                            for(int j = 0;j < input[i+1].size();j++)
                            {
                                if(input[i+1][j] == '\')file_path+="\";
                                else file_path+=input[i+1][j];
                            }
                        }
                    }
                    Function2(ipt,3);
                }
    
            }
        }
    
        return 0;
    }
    View Code

    重点难点:

    功能1:随机数的产生,用逆波兰表达式计算结果

    功能2:要随机产生小数,还要随机产生括号,以及对带有括号的算式的计算

    功能3:对于文件读入的掌握

     三、结对编程的体会

    结对编程确实优于一个人编程,因为每当遇到困难的时候,你的队友的一些建议可能会给你一些灵感。在你程序出错的时候,一般情况下队友更能找出bug,因为队友的思维和你的不同,思维方向更广。就想航海有船长和副手一样,还是有飞行员一般都有两个。

    但是这一切有限的前提是要积极交流。只有积极交流才会产生灵感,如果两个人都是闷头自己做自己的话,那么就无法起到结对编程的作用,甚至还不如一个人编程效率高。

     四、

    事件1:对于怎样进行的计算的问题,刚开始的时候,我们是打算用各种判断的方法来计算,却发现特别复杂,后来上网查询,知道了有逆波兰表达式这个数据结构,而后就解决了这个问题。

    事件2:对于操作数、运算符的保存问题,刚开始是打算用字符串,但是还要识别,感觉很复杂,所以我们就用结构体保存,实现了操作数和运算符的统一保存。

    事件3:对于用户输入的判断,我们突发奇想的把结果处理后保存为字符串,这样判断字符串来判断答案更加方便快捷。

    五、照片

  • 相关阅读:
    node.js 建立live-server
    Django 反向解析
    Boost智能指针——weak_ptr
    boost::intrusive_ptr原理介绍
    shared_ptr 的使用及注意事项
    小感
    JQ对页面中某个DIV的大小变化进行监听
    使用java Apache poi 根据word模板生成word报表
    字节byte自适应转换为B、KB、MB、GB、TB
    jq实现 元素显示后 点击页面的任何位置除元素本身外 隐藏元素
  • 原文地址:https://www.cnblogs.com/wudb527/p/9933811.html
Copyright © 2020-2023  润新知