软件工程课后作业——四则运算Ⅲ(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&¶[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 |
逻辑错误 |
|
描述:算法无法达到预期结果 |