软件工程课后作业——四则运算Ⅲ(C++)

一、设计思路

题目:可以答题并判断对错,最后显示做对几道题。

  在原有的基础上,又拓展了答题模块。

  在结构体中添加了answer属性,把输入的答案与正确答案比较,若相等则计数加一。

二、源代码

(1)四则运算3.cpp

  1 // 四则运算3.cpp : Defines the entry point for the console application.
  2 // 袁佩佩 信1201-1班 20122785 2015/3/18
  3 
  4 #include "stdafx.h"
  5 #include "iostream.h"
  6 #include "stdlib.h"
  7 #include "time.h"
  8 #include "Caculation.h"
  9 #include "iomanip.h"
 10 
 11 //*****判断回答是否正确*****
 12 bool RightOrWrong(Caculation &Q,int answer)
 13 {
 14     if(Q.sign==0)
 15     {
 16         Q.answer=Q.num1+Q.num2;
 17     }
 18     else if(Q.sign==1)
 19     {
 20         Q.answer=Q.num1-Q.num2;
 21     }
 22     else if(Q.sign==2)
 23     {
 24         Q.answer=Q.num1*Q.num2;
 25     }
 26     else
 27         Q.answer=Q.num1/Q.num2;
 28     if(answer==Q.answer)
 29         return true;
 30     else
 31         return false;
 32 }
 33 //******重新生成算术题******
 34 void ReBuild(Caculation &Q)
 35 {
 36     if(para[4]==1)
 37         Q.sign=rand()%4;
 38     else
 39         Q.sign=rand()%2;
 40     Q.num1=rand()%(para[6]-para[5]+1)+para[5];
 41     Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 42 }
 43 
 44 //*****输出函数*****
 45 void Display1(LinkC C,Caculation &Q)
 46 {
 47     int temp,count=0;                                    //count记录重新生成题目的次数
 48     for(int i=1;i<=para[1];i++)
 49     {
 50         cout<<"("<<i<<")";
 51         if(para[4]==1)
 52             Q.sign=rand()%4;                            //有乘除法
 53         else
 54             Q.sign=rand()%2;                            //没有乘除法
 55         Q.num1=rand()%(para[6]-para[5]+1)+para[5];        //随机的(下限~上限)以内的整数
 56         Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 57 RB:        ReBuild(Q);                                        //检查是否有出过的题目
 58         if(count>((para[6]-para[5]+1)*(para[6]-para[5]+1)*100))
 59         {
 60             cout<<endl<<"该难度的题目已出完,请更改出题设置!"<<endl;
 61             break;
 62         }
 63         switch(Q.sign)
 64         {
 65             case 0:
 66                 if(ExistQues(C,Q))
 67                 {
 68                     count++;
 69                     goto RB;
 70                 }
 71                 cout<<Q.num1<<"+"<<Q.num2<<"="<<setw(5);
 72                 break;
 73             case 1:
 74                 if((para[7]==0)&&(Q.num1<Q.num2))
 75                 {                                        //若为负数,则交换
 76                         temp=Q.num1;
 77                         Q.num1=Q.num2;
 78                         Q.num2=temp;
 79                 }
 80                 if(ExistQues(C,Q))
 81                 {
 82                     count++;
 83                     goto RB;
 84                 }
 85                 cout<<Q.num1<<"-"<<Q.num2<<"="<<setw(5);break;
 86             case 2:
 87                 if(ExistQues(C,Q))
 88                 {
 89                     count++;
 90                     goto RB;
 91                 }
 92                 cout<<Q.num1<<"*"<<Q.num2<<"="<<setw(5);break;
 93             case 3:
 94                 while(Q.num2==0)
 95                     Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 96                 if(!para[8])
 97                 {
 98                     while((Q.num1%Q.num2)!=0||Q.num2==0)
 99                     {                                        //重新生成
100                         Q.num1=rand()%(para[6]-para[5]+1)+para[5];
101                         Q.num2=rand()%(para[6]-para[5]+1)+para[5];
102                     }
103                 }
104                 if(ExistQues(C,Q))
105                 {
106                     count++;
107                     goto RB;
108                 }
109                 cout<<Q.num1<<"/"<<Q.num2<<"="<<setw(5);break;
110         }
111         InsertQues(C,Q);
112         if(i%para[2]==0)                                    //一行打印完规定列数,换行
113             for(int j=0;j<=para[3];j++)
114                 cout<<endl;
115     }
116     cout<<endl<<endl;
117 }
118 //*****回答题目函数******
119 void Display2(LinkC C,Caculation &Q)
120 {
121     int temp,count=0,answer=0,right=0;                    //count记录重新生成题目的次数
122     for(int i=1;i<=para[1];i++)
123     {
124         cout<<"("<<i<<")";
125         if(para[4]==1)
126             Q.sign=rand()%4;                            //有乘除法
127         else
128             Q.sign=rand()%2;                            //没有乘除法
129         Q.num1=rand()%(para[6]-para[5]+1)+para[5];                        //随机的(下限~上限)以内的整数
130         Q.num2=rand()%(para[6]-para[5]+1)+para[5];
131 RB:        ReBuild(Q);                                        //检查是否有出过的题目
132         if(count>((para[6]-para[5]+1)*(para[6]-para[5]+1)*100))
133         {
134             cout<<endl<<"该难度的题目已出完,请更改出题设置!"<<endl;
135             break;
136         }
137         switch(Q.sign)
138         {
139             case 0:
140                 if(ExistQues(C,Q))
141                 {
142                     count++;
143                     goto RB;
144                 }
145                 cout<<Q.num1<<"+"<<Q.num2<<"=";
146                 cin>>answer;
147                 if(RightOrWrong(Q,answer))
148                 {
149                     cout<<"\t√";
150                     right++;
151                 }
152                 else
153                     cout<<"\t×";
154                 break;
155             case 1:
156                 if((para[7]==0)&&(Q.num1<Q.num2))
157                 {                                        //若为负数,则交换
158                         temp=Q.num1;
159                         Q.num1=Q.num2;
160                         Q.num2=temp;
161                 }
162                 if(ExistQues(C,Q))
163                 {
164                     count++;
165                     goto RB;
166                 }
167                 cout<<Q.num1<<"-"<<Q.num2<<"=";
168                 cin>>answer;
169                 if(RightOrWrong(Q,answer))
170                 {
171                     cout<<"\t√";
172                     right++;
173                 }
174                 else
175                     cout<<"\t×";
176                 break;
177             case 2:
178                 if(ExistQues(C,Q))
179                 {
180                     count++;
181                     goto RB;
182                 }
183                 cout<<Q.num1<<"*"<<Q.num2<<"=";
184                 cin>>answer;
185                 if(RightOrWrong(Q,answer))
186                 {
187                     cout<<"\t√";
188                     right++;
189                 }
190                     cout<<"\t×";
191                 break;
192             case 3:
193                 while(Q.num2==0)
194                     Q.num2=rand()%(para[6]-para[5]+1)+para[5];
195                 if(!para[8])
196                 {
197                     while((Q.num1%Q.num2)!=0||Q.num2==0)
198                     {                                        //重新生成
199                         Q.num1=rand()%(para[6]-para[5]+1)+para[5];
200                         Q.num2=rand()%(para[6]-para[5]+1)+para[5];
201                     }
202                 }
203                 if(ExistQues(C,Q))
204                 {
205                     count++;
206                     goto RB;
207                 }
208                 cout<<Q.num1<<"/"<<Q.num2<<"=";
209                 cin>>answer;
210                 if(RightOrWrong(Q,answer))
211                 {
212                     cout<<"\t√";
213                     right++;
214                 }
215                     cout<<"\t×";
216                 break;
217         }
218         InsertQues(C,Q);
219         cout<<endl;
220     }
221     cout<<"共回答正确"<<right<<"道题。";
222     cout<<endl<<endl;
223 }
224 
225 //*****判断难度*****
226 void YesOrNo(int para)
227 {
228     if(para)
229         cout<<"";
230     else
231         cout<<"";
232 }
233 //*****查看设置*****
234 void ShowSetting()
235 {
236     system("cls");
237     cout<<"\t/*************四则运算出题系统*************/"<<endl;
238     cout<<"\t题目数量:"<<para[1]<<"个\t\t打印列数:"<<para[2]<<""<<endl;
239     cout<<"\t每行间隔:"<<para[3]<<"行\t\t是否有乘除法:";YesOrNo(para[4]);cout<<endl;
240     cout<<"\t数值范围下限:"<<para[5]<<"\t\t数值范围上限:"<<para[6]<<endl;
241     cout<<"\t是否有负数:";YesOrNo(para[7]);cout<<"\t\t是否有余数:";YesOrNo(para[8]);cout<<endl;
242     cout<<"\t/******************************************/"<<endl;
243 }
244 //*****设置打印方式*****
245 void SetPrint()
246 {
247     system("cls");
248     char move1;
249     cout<<"\t/*************设置打印方式*************/"<<endl;
250     cout<<"\t          0.设置打印列数("<<para[2]<<"列)"<<endl;
251     cout<<"\t          1.设置每行间隔("<<para[3]<<"行)"<<endl;
252     cout<<"\t              2.返回主菜单"<<endl;
253     cout<<"\t/**************************************/"<<endl;
254     cout<<"请选择后续操作(0~2):";
255     cin>>move1;
256     while(move1<'0'||move1>'2')
257     {
258         cout<<"错误!请正确输入操作序号(0~2):";
259         cin>>move1;
260     }
261     switch(move1)
262     {
263         case '0':
264 reset2:        cout<<"新的打印列数(建议7列以内):";
265             cin>>para[2];
266             if(para[2]<0)
267             {
268                 cout<<"出错!请重新输入!"<<endl;
269                 goto reset2;
270             }
271             break;
272         case '1':
273 reset3:        cout<<"新的间隔行数:";
274             cin>>para[3];
275             if(para[3]<0)
276             {
277                 cout<<"出错!请重新输入!"<<endl;
278                 goto reset3;
279             }
280             break;
281         case '2':break;
282     }
283 }
284 //*****判断输入正确*****
285 void Reset(int i)
286 {
287     do
288     {
289         cout<<"请重新设置(是1/否0):";
290         cin>>para[i];                            //此处输入字符出错,但没解决
291     }while(para[i]!=0&&para[i]!=1);
292 }
293 //*****设置题目难度*****
294 void SetLevel()
295 {
296     system("cls");
297     char move2;
298     cout<<"\t/*************设置题目难度*************/"<<endl;
299     cout<<"\t            0.是否有乘除法(";YesOrNo(para[4]);cout<<")"<<endl;
300     cout<<"\t            1.数值范围("<<para[5]<<"~"<<para[6]<<")"<<endl;
301     cout<<"\t            2.是否有负数(";YesOrNo(para[7]);cout<<")"<<endl;
302     cout<<"\t            3.是否有余数(";YesOrNo(para[8]);cout<<")"<<endl;
303     cout<<"\t              4.返回主菜单"<<endl;
304     cout<<"\t/**************************************/"<<endl;
305     cout<<"请选择后续操作(0~4):";
306     cin>>move2;
307     while(move2<'0'||move2>'4')
308     {
309         cout<<"错误!请正确输入操作序号(0~4):";
310         cin>>move2;
311     }
312     switch(move2)
313     {
314         case '0':Reset(4);break;
315         case '1':                                //此处若输入字符,则出错
316 reset1:        cout<<"新的数值下限:";                //但没找到解决方法
317             cin>>para[5];
318             cout<<"新的数值上限:";
319             cin>>para[6];
320             if(para[5]>=para[6])
321             {
322                 cout<<"出错!请重新输入数值范围!"<<endl;
323                 goto reset1;
324             }
325             break;
326         case '2':Reset(7);break;
327         case '3':Reset(8);break;
328         case '4':break;
329     }
330 }
331 //****主页面*****
332 void MainMenu(LinkC &C,Caculation &Q)
333 {
334     char move,save;
335     cout<<"\t/*************四则运算出题系统*************/"<<endl;
336     cout<<"\t                 0.开始出题"<<endl;
337     cout<<"\t               1.设置出题数量"<<endl;
338     cout<<"\t               2.设置打印方式"<<endl;
339     cout<<"\t               3.设置题目难度"<<endl;
340     cout<<"\t               4.查看当前设置"<<endl;
341     cout<<"\t                 5.开始答题"<<endl;
342     cout<<"\t                 6.退出系统"<<endl;
343     cout<<"\t/******************************************/"<<endl;
344     cout<<"请选择后续操作(0~6):";
345     cin>>move;
346     while(move<'0'||move>'6')
347     {
348         cout<<"错误!请正确输入操作序号(0~6):";
349         cin>>move;
350     }
351     switch(move)
352     {
353         case '0':Display1(C,Q);break;
354         case '1':
355 reset4:        cout<<"请设置出题数量(建议100道以内):";
356             cin>>para[1];
357             if(para[1]<=0)
358             {
359                 cout<<"出错!请重新输入!"<<endl;
360                 goto reset4;
361             }
362             break;
363         case '2':SetPrint();break;
364         case '3':SetLevel();break;
365         case '4':ShowSetting();break;
366         case '5':Display2(C,Q);break;
367         case '6':
368             cout<<"是否保存出题记录(是1/否0):";
369             cin>>save;
370             while(save!='1'&&save!='0')
371             {
372                 cout<<"出错!请正确输入(是1/否0):";
373                 cin>>save;
374             }
375             if(save=='1')
376                 WriteQues(C);
377             cout<<"感谢您的使用,再见!"<<endl;
378             para[0]=0;break;
379     }
380 }
381 
382 int main(int argc, char* argv[])
383 {
384     srand((unsigned)time(NULL));    //srand()函数产生一个以当前时间开始的随机种子
385     LinkC Cacu;
386     Caculation ques;
387     InitList(Cacu);
388     ReadQues(Cacu);
389     while(para[0])
390     {
391         system("cls");
392         MainMenu(Cacu,ques);
393         system("pause");
394     }
395     return 0;
396 }

 

(2)Caculation.h

 1 #include "iostream.h"
 2 #include "fstream.h"
 3 
 4 //0退出、1出题数量、2打印列数、3每行间隔、4乘除、5数值范围下限、6数值范围上限、7负数、8余数、9出过的题目数
 5 int para[10]={1,30,3,0,0,0,5,0,0,0};    //默认参数
 6 
 7 //*****四则算术题的数据结构*****
 8 typedef struct
 9 {
10     int num1;
11     int num2;
12     int sign;
13     int answer;
14 }Caculation;
15 typedef struct CNode                    //结点
16 {
17     Caculation ques;
18     struct CNode * next;
19 }CNode,*LinkC;
20 //******题目初始化******
21 void InitList(LinkC &C)
22 {
23     C=new CNode;
24     C->next=NULL;
25 }
26 //******添加题目信息******
27 void InsertQues(LinkC &C,Caculation Q)
28 {                                        //尾插入
29     LinkC tail,temp;
30     tail=C;
31     while(tail&&tail->next!=NULL)
32         tail=tail->next;
33     temp=new CNode;
34     temp->ques=Q;
35     temp->next=NULL;
36     tail->next=temp;
37     tail=temp;
38     para[9]++;
39 }
40 //******判断题目存在******
41 int ExistQues(LinkC C,Caculation Q)
42 {
43     LinkC temp;
44     temp=C->next;
45     while(temp)
46     {
47         if((temp->ques.num1==Q.num1)&&(temp->ques.num2==Q.num2)&&(temp->ques.sign==Q.sign))
48             return 1;                    //当两个数字和算符与链表中的一样,则存在
49         else
50             temp=temp->next;
51     }
52     return 0;
53 }
54 //******读取出过的问题******
55 void ReadQues(LinkC &C)
56 {
57     LinkC temp;
58     ifstream infile("question.txt");
59     for(int i=0;i<10;i++)                //读取参数表
60         infile>>para[i];
61     for(i=0;i<para[9];i++)                //读取出过的题目
62     {
63         temp=new CNode;
64         infile>>temp->ques.num1;
65         infile>>temp->ques.num2;
66         infile>>temp->ques.sign;
67         temp->next=NULL;
68     }
69 }
70 //******写入文件******
71 void WriteQues(LinkC C)
72 {
73     LinkC temp;
74     ofstream outfile("question.txt");
75     if(!outfile)
76     {
77         cout<<"文件存储失败!"<<endl;
78         exit(0);
79     }
80     for(int i=0;i<10;i++)
81         outfile<<para[i]<<" ";
82     for(temp=C->next;temp;temp=temp->next)
83     {
84         outfile<<temp->ques.num1<<" ";
85         outfile<<temp->ques.num2<<" ";
86         outfile<<temp->ques.sign<<" ";
87     }
88 }

三、结果截图

 

四、心得体会

  之所以选这一项,是因为这星期考研课开始了,周六日没有那么多的时间。而我的程序可拓展性好,添加功能比较容易,我就直接在原来的程序上进行了修改。

五、PSP0级

项目计划总结:

周活动总结表

姓名:袁佩佩                                   日期:3/19

日期       任务

听课

编写程序

阅读课本

准备考试

 

 

日总计

周日

 

 

 

 

 

 

 

周一

 300

 

 

 

 

 

 300

周二

 400

 

 

 

 

 

 400

周三

 100

 148

 

 

 

 

 248

周四

 300

 

 

 

 

 

 300

周五

 

 

 

 

 

 

 

周六

 

 

 

 

 

 

 

周总结

 

 

 

 

 

 

 

阶段时间和效率                                        周数(上一次周活动表的周数+1):2

不包括上一周在内的累计时间                                                                         

总计

 1100

 148

 

 

 

 

 1248

平均

 1100

148 

 

 

 

 

 1248

最大

 1100

 148

 

 

 

 

 1248

最小

 1100

 148

 

 

 

 

 1248

以前各周的累计时间                                                                                    

总计

800

268

95 

 

 

 

1163

平均

800

268

95

 

 

 

1163

最大

800

268

95

 

 

 

1163

最小

800

268 

95

 

 

 

1163 

时间记录表:

学生         袁佩佩                                            日期          3/19      

教师        王建民                                             课程           PSP       

日期

开始时间

结束时间

中断时间

净时间

活动

备注

 15/3/18

 14:00

 16:20

 

 80

编写结对开发的作业

 

 

 21:00

22:08

 

 68

改写四则运算3

 

缺陷记录日志:

学生        袁佩佩    

日期         3/19     

教员        王建民    

程序号         3      

日期

编号

类型

引入阶段

排除阶段

修复时间

修复缺陷

 3/18

 

 1

 

 编码

 编译

 2min

 

 描述:#define 时在最后加了分号

 2

 

编码 

执行 

25min 

逻辑错误 

 描述:算法无法达到预期结果

posted @ 2015-03-18 22:36  JJJanepp  阅读(331)  评论(5编辑  收藏  举报