第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:对于用户输入的判断,我们突发奇想的把结果处理后保存为字符串,这样判断字符串来判断答案更加方便快捷。

五、照片

原文地址:https://www.cnblogs.com/wudb527/p/9933811.html