软工作业03

一,题目要求(四则运算3)

1、学生写的程序必须能判定用户的输入答案是否正确,例如程序输出:20 – 5 = ?用户输入15,那么程序就会反馈正确,然后继续出题。直到 30 道题目结束,程序最后告诉用户作对了几道题。

2、程序必须能处理四种运算的混合算式;

n20 – 5 * 2 =?           正确答案是10.
n20– 5 * 2 + 9 / 3 = ?   正确答案是13
3、注意:连续的减法和除法,应该遵守左结合的规定。 连续除法要打括号,否则会引起歧义

二、设计思想

使用栈来实现,因为栈的“先进后出”的特性正好满足了能通过后缀表达式去计算出四则运算式子的结果。而后缀表达式的转化也能使用栈对中缀表达式进行操作从而转化。关于题目的保存和提取可以使用文件读写函数,这样就可以判断用户的答案的正确性了,关于提取,加一个判断是否为操作符的函数就ok了,可以尝试使用类来封装做题的这个程序,在main文件里只加是否继续就ok,

三、源程序代码

类的头文件

 1 #pragma once
 2 #include<iostream>
 3 #include<string>
 4 #include<time.h>
 5 #include <stdio.h>
 6 #include<fstream>
 7 #include<cmath>
 8 #include<sstream>
 9 #include<strstream>
10 #include<math.h>
11 #include<iomanip>
12 #define MAX 100
13 #define False 0
14 #define True 1
15 using namespace std;
16 typedef string SelemType;
17 typedef struct{
18     SelemType *base;
19     SelemType *top;
20     int stacksize;
21 }Sqstack;
22 
23 class ArithMath
24 {
25 private:
26     Sqstack s;
27     string str1[4];    //运算符数组,存储+ - * /
28     int n,m;
29     int num[6];      //随机生成的操作数
30     char str2[25];   //整数转化为的字符数组
31     char str3[25];   //整数转化为的字符数组
32     string str4[100];
33     int OperatorNum[1000];    //运算符数组,每生成一个运算符存进数组
34 
35 public:
36     ArithMath(void);
37     ~ArithMath(void);
38     void InitStack(Sqstack &s)                 //栈的初始化
39     {
40          s.base=new SelemType[MAX];
41          if(!s.base)exit(1);
42          s.top=s.base;
43          s.stacksize =MAX;
44     }
45     void Push(Sqstack &s,SelemType e)          //压入
46     {
47         if(s.top-s.base==s.stacksize)
48             exit(1);
49         *s.top++=e;
50     }
51     void Pop(Sqstack &s,SelemType &e)          //弹出
52     {
53          if(s.top==s.base)
54             exit(1);
55          e=*--s.top;
56     }
57     SelemType GetTop(Sqstack &s)          //取顶
58     {
59          if(s.top==s.base)
60              exit(1);
61          return *(s.top-1);
62     }
63 
64     void workNum();//控制中心函数
65     void changeNum(int n,int y,int min,int max);
66     void changeNum1(int n,int min,int max);
67     int In(SelemType);//判断是否为运算符
68     SelemType Operate(SelemType a1,SelemType theta,SelemType b1);//计算
69     char Precede(string theta1,string theta2);//运算符的计算顺序判断
70     string TiQuString(string,int &);
71     string OPeration(string);
72     void Input(int n,int p,int min,int max,int &j,int &q);
73     void Input1(int n,int p,int min,int max,int &j,int &q);
74     void sort(int min,int max);
75     void sort1(int min,int max);
76     void Simplification(int &m,int &n) ;
77     void Input2(int n,int p,int min,int max,int &j,int &q);
78 };
ArithMath.h

类的cpp文件

  1 #include "ArithMath.h"
  2 
  3 ArithMath::ArithMath(void)
  4 {
  5     str1[0]='+';
  6     str1[1]='-';
  7     str1[2]='*';
  8     str1[3]='/';
  9 }
 10 
 11 ArithMath::~ArithMath(void)
 12 {
 13     
 14 }
 15 
 16 
 17 int ArithMath::In(SelemType ch)                        //判断是否为运算符
 18 {
 19     if(ch=="+"||ch=="-"||ch=="*"||ch=="/"||ch=="("||ch==")"||ch=="#")
 20         return True;
 21      else
 22         return False;
 23 }
 24 SelemType ArithMath::Operate(SelemType a1,SelemType theta,SelemType b1)                          //计算
 25 {
 26     stringstream ss;
 27     SelemType c1;
 28     double m1,m2;
 29     double m3,m4;
 30     m1=atof(a1.c_str());
 31     m2=atof(b1.c_str());
 32     if(theta=="+")
 33         m3=m1+m2;
 34     else if(theta=="-")
 35         m3=m1-m2;
 36     else if(theta=="*")
 37         m3=m1*m2;
 38     else if(theta=="/")
 39         m3=m1/m2;
 40     m4=double((int)(m3*100))/100.0;
 41     ss<<m4;
 42     ss>>c1;
 43     return c1;
 44 }
 45 char ArithMath::Precede(string theta1,string theta2)                     //运算符的计算顺序判断
 46 {
 47     char chx;
 48     if(theta1=="+")
 49     {
 50         if(theta2=="*"||theta2=="/"||theta2=="(")
 51             chx = '<';
 52         else
 53             chx = '>';   
 54     }
 55     else if(theta1=="-")
 56     {
 57         if(theta2=="*"||theta2=="/"||theta2=="(")
 58             chx = '<';
 59         else
 60             chx = '>';   
 61     }
 62     else if(theta1=="*")
 63     {
 64         if(theta2=="(")
 65             chx = '<';
 66         else
 67             chx = '>';   
 68     }
 69     else if(theta1=="/")
 70     {
 71         if(theta2=="(")
 72             chx = '<';
 73         else
 74             chx = '>';   
 75     }
 76     else if(theta1=="(")
 77     {
 78          if(theta2==")")
 79              chx = '=';
 80          else if(theta2=="#")
 81              chx='$';
 82          else
 83             chx = '<';   
 84     }
 85     else if(theta1==")")
 86     {
 87         if(theta2=="(")
 88             chx = '$';
 89         else
 90             chx = '>';   
 91     }
 92     else if(theta1=="#")
 93     {
 94         if(theta2=="#")
 95             chx = '=';
 96         else if(theta2==")")
 97             chx='$';
 98         else
 99             chx = '<';   
100     }
101      return chx;
102 }
103 string ArithMath::TiQuString(string str,int &i)
104 {
105     string ch;
106     char *q;
107     string p;
108     p=str;
109     q=&p[i];
110     ch=ch+*q;
111     if((*q>='0')&&(*q<='9'))
112     {
113         i++;
114         int j=1;
115         while((*(q+j)>='0')&&(*(q+j)<='9'))
116         {
117             ch=ch+*(q+j);
118             j++; 
119         }
120         i=i+j-1;    
121     }
122     else
123     {
124         ch=*q;
125         i++;
126     }
127     return ch;
128 }
129 string ArithMath::OPeration(string str)
130 {
131 
132      string str1;
133      str1=str+"#";
134      int i=0;
135      string ch;
136      ch=TiQuString(str1,i);
137      SelemType theta,x1,a1,b1;
138      Sqstack OPND,OPTR;
139      InitStack(OPTR);
140      InitStack(OPND);
141      Push(OPTR,"#");
142      while(ch!="#"||GetTop(OPTR)!="#")
143      {
144          int f;
145          f=In(ch);
146          if(f!=True)
147          {
148              Push(OPND,ch);
149              ch=TiQuString(str1,i);
150          }
151          else
152             {
153                 switch(Precede(GetTop(OPTR),ch))
154                 {
155                 case '<':
156                     {
157                         Push(OPTR,ch);
158                         ch=TiQuString(str1,i);
159                         break;
160                     }
161                 case '>':
162                     {
163                         Pop(OPTR,theta);
164                         Pop(OPND,b1);Pop(OPND,a1);
165                         Push(OPND,Operate(a1,theta,b1));
166                         break;
167                     }
168                 case '=':
169                     {
170                         Pop(OPTR,x1);
171                         ch=TiQuString(str1,i);
172                         break;
173                     }
174                 case '$':
175                     {
176                         cout<<"该表达式有错";
177                         break;
178                     }
179                 default:break;
180                 }
181          }
182      }
183      return GetTop(OPND);
184 
185 } 
186 void ArithMath::Input(int n,int p,int min,int max,int &j,int &q)
187 {
188     int num1,num2,num3,num4,num5;                        //随机数
189     int c=0;                                             //指向第一个运算符数组的下标
190     int s=0;                                             //括号的个数
191     string str;
192     ofstream outfile;    
193     outfile.open("a.txt",ios::app);                  
194     if(!outfile)
195     {
196         cerr<<"OPEN ERROR!"<<endl;
197         exit(0);
198     }
199     num1=rand()%(max-min+1)+min;
200     num2=rand()%(max-min+1)+min;
201     num3=rand()%4;                                       //随机数指向运算符数组的下标
202     itoa(num1,str2,10);                                  //整数转化为字符数组
203     itoa(num2,str3,10);                                   //整数转化为字符数组
204     str=str2+str1[num3]+str3;                             //生成表达式
205     OperatorNum[c]=num3;                                  //当前生成的符号存入OperatorNum数组里
206     c++;
207     n=n-2;                       //消耗了两个操作数
208     while(n!=0)                 //当n不等于0时,循环生成str,即表达式+符号+表达式的形式
209     {    
210         num4=rand()%2;
211         if(num4==0)             //上一个str放在符号的左边
212         {
213             num5=rand()%2;
214             if(s<=3)

215             {
216                 if(num5==0)            //上一个str不加括号
217                 {
218                     num3=rand()%4;
219                     OperatorNum[c]=num3;
220                     c++;
221                     num1=rand()%(max-min+1)+min;
222                     itoa(num1,str2,10);
223                     if((num3==3)&&(OperatorNum[c-2]==3))            //避免生成6/3/2的形式
224                         str="("+str+")"+str1[num3]+str2;
225                     else
226                         str=str+str1[num3]+str2;
227                 }
228                 else                           //上一个str加括号
229                 {

230                     num3=rand()%4;
231                     num1=rand()%(max-min+1)+min;
232                     itoa(num1,str2,10);
233                     str="("+str+")"+str1[num3]+str2;
234                     s++;
235                 }
236             }
237             else

238             {
239                 num3=rand()%4;
240                 OperatorNum[c]=num3;
241                 c++;
242                 num1=rand()%(max-min+1)+min;
243                 itoa(num1,str2,10);
244                 if((num3==3)&&(OperatorNum[c-2]==3))            //避免生成6/3/2的形式
245                     str="("+str+")"+str1[num3]+str2;
246                 else
247                     str=str+str1[num3]+str2;
248             }
249         }
250         else                              //上一个str放在符号的右边
251         {
252             num5=rand()%2;
253             if(s<=3)
254             {
255                 if(num5==0)                    // 上一个str不加括
256                 {
257                     num3=rand()%4;
258                     OperatorNum[c]=num3;
259                     c++;
260                     num1=rand()%(max-min+1)+min;
261                     itoa(num1,str2,10);
262                     if((num3==3)&&(OperatorNum[c-2]==3))
263                         str=str2+str1[num3]+"("+str+")";
264                     else
265                         str=str2+str1[num3]+str;
266                 }
267                 else                         //上一个str加括号
268                 {
269                     num3=rand()%4;
270                     num1=rand()%(max-min+1)+min;
271                     itoa(num1,str2,10);
272                     str=str2+str1[num3]+"("+str+")";
273                     s++;
274                 }
275             }
276             else
277             {
278                 num3=rand()%4;
279                 OperatorNum[c]=num3;
280                 c++;
281                 num1=rand()%(max-min+1)+min;
282                 itoa(num1,str2,10);
283                 if((num3==3)&&(OperatorNum[c-2]==3))
284                     str=str2+str1[num3]+"("+str+")";
285                 else
286                     str=str2+str1[num3]+str;
287             }
288         }
289         n--;                                //消耗一个操作数
290     }
291     string result1,result2;               //result1表示用户输入的答案,result2表示程序计算的结果
292     str4[p]=str;                         //把str存入字符串数组str4中
293     for(int i=0;i<p;i++)                 //查询四则运算式是否有重复
294         if(str4[i]==str4[p])
295              Input(m,p,min,max,j,q);
296     cout<<str4[p]<<"=";
297     result2=OPeration(str);                  //计算四则表达式
298     cin>>result1;
299     if(result1==result2)                        //判断结果是否正确
300     {
301         cout<<"计算正确";
302         j++;
303     }
304     else
305     {
306         cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2;
307         q++;
308     }
309     outfile<<str4[p]<<endl;
310     cout<<endl;
311 }
312 void ArithMath::Input1(int n,int p,int min,int max,int &j,int &q)
313 {
314     int num1,num2,num3,num4;
315     int c=0;
316     int s=0;
317     string str;
318     ofstream outfile;
319     outfile.open("a.txt",ios::app);                  
320     if(!outfile)
321     {
322         cerr<<"OPEN ERROR!"<<endl;
323         exit(0);
324     }
325     num1=rand()%(max-min+1)+min;
326     num2=rand()%(max-min+1)+min;
327     num3=rand()%4;
328     itoa(num1,str2,10);
329     itoa(num2,str3,10);
330     str=str2+str1[num3]+str3;
331     OperatorNum[c]=num3;
332     c++;
333     n=n-2;
334     while(n!=0)                 //当n不等于0时,循环生成str,即表达式+符号+表达式的形式
335     {    
336         num4=rand()%2;
337         if(num4==0)             //上一个str放在符号的左边
338         {
339             num3=rand()%4;
340             OperatorNum[c]=num3;
341             c++;
342             num1=rand()%(max-min+1)+min;
343             itoa(num1,str2,10);
344             if((num3==3)&&(OperatorNum[c-2]==3))            //避免生成6/3/2的形式
345                 str="("+str+")"+str1[num3]+str2;
346             else
347                 str=str+str1[num3]+str2;
348         }
349         else                              //上一个str放在符号的右边
350         {
351             num3=rand()%4;
352             OperatorNum[c]=num3;
353             c++;
354             num1=rand()%(max-min+1)+min;
355             itoa(num1,str2,10);
356             if((num3==3)&&(OperatorNum[c-2]==3))
357                 str=str2+str1[num3]+"("+str+")";
358             else
359                 str=str2+str1[num3]+str;
360         }        
361         n--;
362     }
363     string result1,result2;
364     str4[p]=str;                         //把str存入字符串数组str4中
365     for(int i=0;i<p;i++)                 //查询四则运算式是否有重复
366         if(str4[i]==str4[p])
367              Input(m,p,min,max,j,q);
368     cout<<str4[p]<<"=";
369     result2=OPeration(str);
370     cin>>result1;
371     if(result1==result2)
372     {
373         cout<<"计算正确";
374         j++;
375     }
376     else
377     {
378         cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2;
379         q++;
380     }
381     outfile<<str4[p]<<endl;
382     cout<<endl;
383 }
384 void ArithMath::sort(int min,int max){                      //生成四个随机数并排序
385     num[0]=rand()%(max-min+1)+min;
386     num[1]=rand()%(max-min+1)+min;
387     num[2]=rand()%(max-min+1)+min;
388     num[3]=rand()%(max-min+1)+min;
389     for(int i=0;i<4;i++){
390         for(int j=0;j<i;j++){ 
391             if(num[i]>num[j])
392             {
393                 int temp=0;
394                 temp=num[i];
395                 num[i]=num[j];
396                 num[j]=temp;
397             }
398         }
399     }    
400 }
401 void ArithMath::sort1(int min,int max)                                    //生成两个随机数,并排序
402 {                     
403     num[4]=rand()%(max-min+1)+min;
404     num[5]=rand()%(max-min+1)+min;
405     for(int i=4;i<6;i++){
406         for(int j=4;j<i;j++){ 
407             if(num[i]>num[j])
408             {
409                 int temp=0;
410                 temp=num[i];
411                 num[i]=num[j];
412                 num[j]=temp;
413             }
414         }
415     }    
416 }
417 void ArithMath::Simplification(int &m,int &n)                                    //真分数化简
418 {
419     int x,y,i,p;                                                     //公约数p
420     if(m>=n)
421     {
422         x=n;
423         y=m;
424     }
425     if(m<n)
426     {
427         x=m;
428         y=n;
429     }
430     for(i=x;i>0;i--)
431     {
432         if(x%i==0&&y%i==0)
433         {
434             p=i;
435             break;
436         }
437     }
438     m=m/p;
439     n=n/p;
440 }
441 void ArithMath::Input2(int n,int p,int min,int max,int &j,int &q)
442 {
443     int num3,num4,s=0;
444     string str,strr2,strr3,str5,str6,str7,str8,str9;
445     stringstream ss1,ss2,ss3,ss4,ss5,ss6,ss7,ss8;
446     ofstream outfile;
447     outfile.open("a.txt",ios::app);                  
448     if(!outfile)
449     {
450         cerr<<"OPEN ERROR!"<<endl;
451         exit(0);
452     }
453     num3=rand()%4;
454     sort(min,max);
455     Simplification(num[0],num[3]);
456     Simplification(num[1],num[2]);
457     ss1<<num[0];
458     ss1>>strr2;
459     ss2<<num[1];
460     ss2>>strr3;
461     ss3<<num[2];
462     ss3>>str5;
463     ss4<<num[3];
464     ss4>>str6;
465     if((str5!=strr3)&&(str6!=strr2))                                             //避免生成分子分母相等的表达式
466         str="("+str5+"/"+strr3+")"+str1[num3]+"("+str6+"/"+strr2+")";
467     else if(str5==strr3)
468         str=str5+str1[num3]+"("+str6+"/"+strr2+")";
469     else if(str6==strr2)
470         str="("+str5+"/"+strr3+")"+str1[num3]+str6;
471     n=n-4;
472     while(n!=0)                 //当n不等于0时,循环生成str,即表达式+符号+表达式的形式
473     {    
474         num4=rand()%2;
475         if(num4==0)             //上一个str放在符号的左边
476         {
477             sort1(min,max);
478             Simplification(num[4],num[5]);
479             num3=rand()%4;
480             ss5<<num[4];
481             ss5>>str7;
482             ss6<<num[5];
483             ss6>>str8;
484             if(str7!=str8)                                                //避免生成分子分母相等的表达式
485                 str9="("+str8+"/"+str7+")";
486             else
487                 str9=str8;
488             str=str+str1[num3]+str9;
489         }
490         else                              //上一个str放在符号的右边
491         {    
492             sort1(min,max);
493             Simplification(num[4],num[5]);
494             num3=rand()%4;
495             ss7<<num[4];
496             ss7>>str7;
497             ss8<<num[5];
498             ss8>>str8;
499             if(str7!=str8)                                                         //避免生成分子分母相等的表达式
500                 str9="("+str8+"/"+str7+")";
501             else
502                 str9=str8;
503             str=str9+str1[num3]+str;
504         }        
505         n=n-2;
506     }
507     string result1,result2;
508     str4[p]=str;                         //把str存入字符串数组str4中
509     for(int i=0;i<p;i++)                 //查询四则运算式是否有重复
510         if(str4[i]==str4[p])
511              Input2(m,p,min,max,j,q);
512     cout<<str4[p]<<"=";
513     result2=OPeration(str);
514     cin>>result1;
515     if(result1==result2)
516     {
517         cout<<"计算正确";
518         j++;
519     }
520     else
521     {
522         cout<<"计算错误,答案是"<<setprecision(2)<<fixed<<result2;
523         q++;
524     }
525     outfile<<str4[p]<<endl;
526     cout<<endl;
527 }
528 void ArithMath::changeNum(int n,int y,int min,int max)
529 {
530     int j=0,q=0,num6;
531     if(y==1)
532     {
533         for(int i=0;i<n;i++)                  
534         {
535             num6=rand()%9+2;
536             switch(num6)
537             {
538             case 2:Input(2,i,min,max,j,q);break;
539             case 3:Input(3,i,min,max,j,q);break;
540             case 4:Input(4,i,min,max,j,q);break;
541             case 5:Input(5,i,min,max,j,q);break;
542             case 6:Input(6,i,min,max,j,q);break;
543             case 7:Input(7,i,min,max,j,q);break;
544             case 8:Input(8,i,min,max,j,q);break;
545             case 9:Input(9,i,min,max,j,q);break;
546             case 10:Input(10,i,min,max,j,q);break;    
547             }
548         }
549         cout<<"本次测试结束"<<endl;
550         cout<<"正确----"<<j<<"道题,错误----"<<q<<"道题"<<endl;
551     }
552     else
553     {
554         for(int i=0;i<n;i++)                  
555         {
556             num6=rand()%9+2;
557             switch(num6)
558             {
559             case 2:Input1(2,i,min,max,j,q);break;
560             case 3:Input1(3,i,min,max,j,q);break;
561             case 4:Input1(4,i,min,max,j,q);break;
562             case 5:Input1(5,i,min,max,j,q);break;
563             case 6:Input1(6,i,min,max,j,q);break;
564             case 7:Input1(7,i,min,max,j,q);break;
565             case 8:Input1(8,i,min,max,j,q);break;
566             case 9:Input1(9,i,min,max,j,q);break;
567             case 10:Input1(10,i,min,max,j,q);break;    
568             }
569         }
570         cout<<"本次测试结束"<<endl;
571         cout<<"正确----"<<j<<"道题,错误----"<<q<<"道题"<<endl;
572         
573         
574     }
575 }
576 void ArithMath::changeNum1(int n,int min,int max)
577 {
578     int j=0,q=0,p,num6;
579     for(int i=0;i<n;i++)                  
580     {
581         num6=rand()%4;
582         p=4+2*i;                               //表示生成的操作数的个数
583         switch(p)
584         {
585         case 4:Input2(4,i,min,max,j,q);break;
586         case 6:Input2(6,i,min,max,j,q);break;
587         case 8:Input2(8,i,min,max,j,q);break;
588         case 10:Input2(10,i,min,max,j,q);break;    
589         }
590     }
591         cout<<"本次测试结束"<<endl;
592         cout<<"正确----"<<j<<"道题,错误----"<<q<<"道题"<<endl;
593 }
594 void ArithMath::workNum()//控制中心函数
595 {
596     cout<<"**********************欢迎您使用四则运算生成器3.0!**************************"<<endl;
597     int x,y,max,min;
598     srand((unsigned)time(NULL));
599     ofstream outfile1;
600     outfile1.open("a.txt");
601     if(!outfile1)
602     {
603         cerr<<"OPEN ERROR!"<<endl;
604         exit(0);
605     }
606     cout<<"         1.整数的四则运算                  "<<endl;
607     cout<<"         2.真分数的四则运算                "<<endl;
608     cout<<"请选择:";
609     cin>>x;
610     while(x!=1&&x!=2)
611     {
612         cout<<"输入有误,请重新输入!"<<endl;
613         cin>>x;
614     }
615     switch(x)
616     {
617         case 1:
618             {
619                 cout<<"取值范围最小值(大于等于1):";
620                 cin>>min;
621                 cout<<"取值范围最大值:";
622                 cin>>max;
623                 cout<<"有(无)括号运算(注释:真分数必须加括号,以防形成6/3/2的形式)---有(1),无(0):";
624                 cin>>y;
625                 cout<<"题目数量:";
626                 cin>>n;
627                 cout<<"      请开始答题          "<<endl;
628                 changeNum(n,y,min,max);
629                 break;
630             }
631         case 2:
632             {
633                 cout<<"取值分子分母范围最小值(大于等于1):";
634                 cin>>min;
635                 cout<<"取值分子分母范围最大值(大于等于1):";
636                 cin>>max;
637                 cout<<"题目数量:";
638                 cin>>n;
639                 cout<<"       请开始答题          "<<endl;
640                 changeNum1(n,min,max);
641                 break;
642             }
643     }
644     cout<<"****************************************************************************"<<endl;
645 }
ArithMath.cpp

main.cpp

 1 #include "ArithMath.h"
 2 void main()
 3 {
 4     int p=1;
 5     do
 6     {
 7         ArithMath s;
 8         s.workNum();
 9         cout<<"是否继续生成运算题(输入1则生成否则不生成):"<<endl;
10         cin>>p;
11         while(p!=1&&p!=0)
12         {
13             cout<<"请输入1或0(输入1则生成否则不生成):"<<endl;
14             cin>>p;
15         }
16     }while(p=1);
17     cout<<"The End!"<<endl;
18 }
main.cpp

四、运行结果截图

五、编程总结分析

数据结构和算法真是个好东西啊,以后一定有更多的地方用的到,后悔没有好好学呀,欠下的总得还的,看来得把栈和队列好好补补了

六、时间记录日志

日期 开始时间 结束时间 净时间 活动 备注
3.21 8:00,16:00 10:00,17:00 3h 上课,编程  单元测试
3.22 19:00 20:00 1h 博客  读后感
3.23 19:00 20:00 1h 编程  
3.24 19:00 20:00 1h 编程  
3.25 19:00 20:00 1h 编程  
3.26 9:00,13:00 12:30 17:00 7.5h 编程  
原文地址:https://www.cnblogs.com/420Rock/p/5302718.html