软件工程随堂小作业——随机四则运算Ⅱ(C++)

一、设计思路

  设计思路已给出,此处不再赘述。

二、源代码

(1)四则运算2.cpp(源文件)

 

  1 // 四则运算2.cpp : Defines the entry point for the console application.
  2 // 袁佩佩 信1201-1班 20122785 2015/3/15
  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 void ReBuild(Caculation &Q)
 13 {
 14     if(para[4]==1)
 15         Q.sign=rand()%4;
 16     else
 17         Q.sign=rand()%2;
 18     Q.num1=rand()%(para[6]-para[5]+1)+para[5];
 19     Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 20 }
 21 //*****输出函数******
 22 void Display(LinkC C,Caculation &Q)
 23 {
 24     int temp,count=0;                                    //count记录重新生成题目的次数
 25     for(int i=1;i<=para[1];i++)
 26     {
 27         cout<<"("<<i<<")";
 28         if(para[4]==1)
 29             Q.sign=rand()%4;                            //有乘除法
 30         else
 31             Q.sign=rand()%2;                            //没有乘除法
 32         Q.num1=rand()%(para[6]-para[5]+1)+para[5];                        //随机的(下限~上限)以内的整数
 33         Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 34 RB:        ReBuild(Q);                                        //检查是否有出过的题目
 35         if(count>((para[6]-para[5]+1)*(para[6]-para[5]+1)*100))
 36         {
 37             cout<<endl<<"该难度的题目已出完,请更改出题设置!"<<endl;
 38             break;
 39         }
 40         switch(Q.sign)
 41         {
 42             case 0:
 43                 if(ExistQues(C,Q))
 44                 {
 45                     count++;
 46                     goto RB;
 47                 }
 48                 cout<<Q.num1<<"+"<<Q.num2<<"="<<setw(5);
 49                 break;
 50             case 1:
 51                 if((para[7]==0)&&(Q.num1<Q.num2))
 52                 {                                        //若为负数,则交换
 53                         temp=Q.num1;
 54                         Q.num1=Q.num2;
 55                         Q.num2=temp;
 56                 }
 57                 if(ExistQues(C,Q))
 58                 {
 59                     count++;
 60                     goto RB;
 61                 }
 62                 cout<<Q.num1<<"-"<<Q.num2<<"="<<setw(5);break;
 63             case 2:
 64                 if(ExistQues(C,Q))
 65                 {
 66                     count++;
 67                     goto RB;
 68                 }
 69                 cout<<Q.num1<<"*"<<Q.num2<<"="<<setw(5);break;
 70             case 3:
 71                 while(Q.num2==0)
 72                     Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 73                 if(!para[8])
 74                 {
 75                     while((Q.num1%Q.num2)!=0||Q.num2==0)
 76                     {                                        //重新生成
 77                         Q.num1=rand()%(para[6]-para[5]+1)+para[5];
 78                         Q.num2=rand()%(para[6]-para[5]+1)+para[5];
 79                     }
 80                 }
 81                 if(ExistQues(C,Q))
 82                 {
 83                     count++;
 84                     goto RB;
 85                 }
 86                 cout<<Q.num1<<"/"<<Q.num2<<"="<<setw(5);break;
 87         }
 88         InsertQues(C,Q);
 89         if(i%para[2]==0)                                    //一行打印完规定列数,换行
 90             for(int j=0;j<=para[3];j++)
 91                 cout<<endl;
 92     }
 93     cout<<endl<<endl;
 94 }
 95 //*****判断难度*****
 96 void YesOrNo(int para)
 97 {
 98     if(para)
 99         cout<<"";
100     else
101         cout<<"";
102 }
103 //*****查看设置*****
104 void ShowSetting()
105 {
106     system("cls");
107     cout<<"\t/*************四则运算出题系统*************/"<<endl;
108     cout<<"\t题目数量:"<<para[1]<<"个\t\t打印列数:"<<para[2]<<""<<endl;
109     cout<<"\t每行间隔:"<<para[3]<<"行\t\t是否有乘除法:";YesOrNo(para[4]);cout<<endl;
110     cout<<"\t数值范围下限:"<<para[5]<<"\t\t数值范围上限:"<<para[6]<<endl;
111     cout<<"\t是否有负数:";YesOrNo(para[7]);cout<<"\t\t是否有余数:";YesOrNo(para[8]);cout<<endl;
112     cout<<"\t/******************************************/"<<endl;
113 }
114 //*****设置打印方式*****
115 void SetPrint()
116 {
117     system("cls");
118     char move1;
119     cout<<"\t/*************设置打印方式*************/"<<endl;
120     cout<<"\t          0.设置打印列数("<<para[2]<<"列)"<<endl;
121     cout<<"\t          1.设置每行间隔("<<para[3]<<"行)"<<endl;
122     cout<<"\t              2.返回主菜单"<<endl;
123     cout<<"\t/**************************************/"<<endl;
124     cout<<"请选择后续操作(0~2):";
125     cin>>move1;
126     while(move1<'0'||move1>'2')
127     {
128         cout<<"错误!请正确输入操作序号(0~2):";
129         cin>>move1;
130     }
131     switch(move1)
132     {
133         case '0':
134 reset2:        cout<<"新的打印列数(建议7列以内):";
135             cin>>para[2];
136             if(para[2]<0)
137             {
138                 cout<<"出错!请重新输入!"<<endl;
139                 goto reset2;
140             }
141             break;
142         case '1':
143 reset3:        cout<<"新的间隔行数:";
144             cin>>para[3];
145             if(para[3]<0)
146             {
147                 cout<<"出错!请重新输入!"<<endl;
148                 goto reset3;
149             }
150             break;
151         case '2':break;
152     }
153 }
154 //*****判断输入正确*****
155 void Reset(int i)
156 {
157     do
158     {
159         cout<<"请重新设置(是1/否0):";
160         cin>>para[i];                //此处输入字符出错,但没解决
161     }while(para[i]!=0&&para[i]!=1);
162 }
163 //*****设置题目难度*****
164 void SetLevel()
165 {
166     system("cls");
167     char move2;
168     cout<<"\t/*************设置题目难度*************/"<<endl;
169     cout<<"\t            0.是否有乘除法(";YesOrNo(para[4]);cout<<")"<<endl;
170     cout<<"\t            1.数值范围("<<para[5]<<"~"<<para[6]<<")"<<endl;
171     cout<<"\t            2.是否有负数(";YesOrNo(para[7]);cout<<")"<<endl;
172     cout<<"\t            3.是否有余数(";YesOrNo(para[8]);cout<<")"<<endl;
173     cout<<"\t              4.返回主菜单"<<endl;
174     cout<<"\t/**************************************/"<<endl;
175     cout<<"请选择后续操作(0~4):";
176     cin>>move2;
177     while(move2<'0'||move2>'4')
178     {
179         cout<<"错误!请正确输入操作序号(0~4):";
180         cin>>move2;
181     }
182     switch(move2)
183     {
184         case '0':Reset(4);break;
185         case '1':                                //此处若输入字符,则出错
186 reset1:        cout<<"新的数值下限:";                //但没找到解决方法
187             cin>>para[5];
188             cout<<"新的数值上限:";
189             cin>>para[6];
190             if(para[5]>=para[6])
191             {
192                 cout<<"出错!请重新输入数值范围!"<<endl;
193                 goto reset1;
194             }
195             break;
196         case '2':Reset(7);break;
197         case '3':Reset(8);break;
198         case '4':break;
199     }
200 }
201 //****主页面*****
202 void MainMenu(LinkC &C,Caculation &Q)
203 {
204     char move,save;
205     cout<<"\t/*************四则运算出题系统*************/"<<endl;
206     cout<<"\t                 0.开始出题"<<endl;
207     cout<<"\t               1.设置出题数量"<<endl;
208     cout<<"\t               2.设置打印方式"<<endl;
209     cout<<"\t               3.设置题目难度"<<endl;
210     cout<<"\t               4.查看当前设置"<<endl;
211     cout<<"\t                 5.退出系统"<<endl;
212     cout<<"\t/******************************************/"<<endl;
213     cout<<"请选择后续操作(0~5):";
214     cin>>move;
215     while(move<'0'||move>'5')
216     {
217         cout<<"错误!请正确输入操作序号(0~5):";
218         cin>>move;
219     }
220     switch(move)
221     {
222         case '0':Display(C,Q);break;
223         case '1':
224 reset4:        cout<<"请设置出题数量(建议100道以内):";
225             cin>>para[1];
226             if(para[1]<=0)
227             {
228                 cout<<"出错!请重新输入!"<<endl;
229                 goto reset4;
230             }
231             break;
232         case '2':SetPrint();break;
233         case '3':SetLevel();break;
234         case '4':ShowSetting();break;
235         case '5':
236             cout<<"是否保存出题记录(是1/否0):";
237             cin>>save;
238             while(save!='1'&&save!='0')
239             {
240                 cout<<"出错!请正确输入(是1/否0):";
241                 cin>>save;
242             }
243             if(save=='1')
244                 WriteQues(C);
245             cout<<"感谢您的使用,再见!"<<endl;
246             para[0]=0;break;
247     }
248 }
249 
250 int main(int argc, char* argv[])
251 {
252     srand((unsigned)time(NULL));    //srand()函数产生一个以当前时间开始的随机种子
253     LinkC Cacu;
254     Caculation ques;
255     InitList(Cacu);
256     ReadQues(Cacu);
257     while(para[0])
258     {
259         system("cls");
260         MainMenu(Cacu,ques);
261         system("pause");
262     }
263     return 0;
264 }

 

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

 该程序不是特别完美,若有bug和改进方案,欢迎交流。

三、截图

第一次使用时,程序默认10以内四则运算10道题,有负数余数,分三列打印,每行间隔一行。见下图。

 

               对参数进行一些修改。见下图。

                          对打印方式进行修改。见下图。

对题目的一些设置

退出系统,可选择保存出过的题目和参数设置。

 后来经过我的代码优化,当某种类型的题目全部都出过以后,会提示。

首先当前设置如下。

连续出题多次发现

四、PSP0级 记录表

项目计划总结:

周活动总结表

姓名:袁佩佩                                       日期:15/3/14

日期       任务

听课

编写程序

阅读课本

准备考试

 

 

日总计

周日

 

 

 

 

 

 

 

周一

 

 

 

 

 

 

 

周二

 300

 

 20

 

 

 

 320

周三

 100

 70

 30

 

 

 

 200

周四

 200

 115

 5

 

 

 

 320

周五

 200

 40

 30

 

 

 

 270

周六

 

 43

 10

 

 

 

 53

周总结

 800

 268

 95

 

 

 

 1163

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

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

总计

 

 

 

 

 

 

 

平均

 

 

 

 

 

 

 

最大

 

 

 

 

 

 

 

最小

 

 

 

 

 

 

 

以前各周的累计时间                                                                                    

总计

800

268

95

 

 

 

1163

平均

 800

268 

95 

 

 

 

1163

最大

800 

268

95 

 

 

 

1163

最小

800 

268

95 

 

 

 

1163

时间记录表:

学生         袁佩佩                                            日期        15/3/14    

教师        王建民                                             课程           PSP       

日期

开始时间

结束时间

中断时间

净时间

活动

备注

 15/3/11

 8:00

 9:50

 10

 100

计算机网络上课

 课间10分钟休息

 

 16:20

16:50 

 

 30

阅读《梦断代码》

 

 

17: 44

 18:37

 20

 33

编写四则运算程序 

填写PSP记录表 

 

 23:00

23:37 

 

 37

 编写四则运算程序

 

 3/12

10:10

12:00

10

100

计算机接口技术上课

课间休息

 

14:00

15:50

10

100

嵌入式开发技术上课

课间休息

 

 16:50

 17:50

 

 60

 四则运算

 

 

 22:35

 23:30

 

 55

 四则运算

 

3/13

8:00

12:00

40

200

上课 软件工程

操作系统

课间休息

 

21:00

23:00

20

100

编写四则运算

聊天、上厕所

3/14

12:12

12:55

 

43

优化代码

 


缺陷记录日志:
 

学生       袁佩佩   

日期        3/14    

教员       王建民   

程序号        2      

日期

编号

类型

引入阶段

排除阶段

修复时间

修复缺陷

 15/3/11

 1

 

 编码

编译 

 2min

 

 描述:实参与形参类型不匹配

 3/12

 2

 

 编码

 执行

 5min

 逻辑错误

 描述:检查重复的代码没写全,导致没能有效的避免重复。

 3/13

 3

 

 编码

 执行

 5min

 逻辑错误

 描述:引入数据结构后,原来的参数和变量没有彻底转换完

 3/14

 4

 

 编码

编译 

 1min

 

 描述:忘加右括号了“)”

五、心得体会

  设计思想里已经写了,编写程序的时候,我是渐进式的自顶向下的开发的。但是我不太清楚编写代码时,该不该用自顶向下。因为我比较注重细节,先写框架再写核心往往会导致编出来的程序虎头蛇尾。而且这次我是最后才加上的数据结构,以至于之前写的变量名、参数等等都要变更,有些麻烦。以后我会训练自己自底向上写代码的能力。我有个坏毛病就是,边写边思考,有时候这个问题还差一点就解决了,结果就又扯到另一个问题上了。我在与其他同学交流的过程中,也了解到“下手”之前,必须要先把整个程序在心里构建的差不多了,再敲代码。多和编程能力强或编程习惯好的同学交流,多向他们学习,也是受益匪浅啊。

  最后就是,数据结构部分我是借鉴之前数据结构小学期自己做的员工管理系统来编写的,回忆起了链表以及相关操作的知识。

 

posted @ 2015-03-11 18:38  JJJanepp  阅读(350)  评论(0编辑  收藏  举报