关于学生信息管理系统的优化和改进
项目来源:室友的作业项目
使用的是dev c++编译器
关于本篇博客内容,我将分成了三个部分进行讲述:源代码的解读、二次重开发后程序的介绍和在做完对他人代码的解读和重开发后自己的一些感想。
一、 源代码的解读
1.功能解读
源代码的程序运行主界面:
主要功能有:1).学生信息总览 2)添加学生信息 3)删除学生信息 4)模糊查询学生信息 5)回收站 0)退出
1)学生信息总览
2)添加学生信息
3)删除学生信息
4)模糊查询学生信息
5)回收站
0.)退出会保存信息
结束动画:
2.对应功能所使用的方法
1.学生信息总览
void allstu(vector<student*>&stu,int flag=1) //总览 { if(flag){ putchar(55); system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 学生总览 |\n"; cout<<"+----------------------------------------------------------------+\n"; cout<<"共"<<stu.size()<<"学生"<<endl<<endl; } for(int i=0;i<stu.size();i++){ stu[i]->display(); cout<<"\n"; } if(flag){ cout<<"输入0返回"<<endl; while(getchar()!=48); } }
2。添加学生信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int addstu(vector<student*>&stu) //add 2 { 3 system("cls"); 4 cout<<"+----------------------------------------------------------------+\n"; 5 cout<<"| 增加学生 |\n"; 6 cout<<"+----------------------------------------------------------------+\n"; 7 string name="abcdef"; //名 8 char sex='M'; //性 9 int building=1; //楼 10 int room=506; //房 11 string number="12345678901"; //电话号码 12 string WeChat="123456"; //微信 13 string QQ="1234567890"; //QQ 14 string stuid="2052538"; //学号 15 string _class="abcd01"; //班级 16 int year=2021; //年 17 int mon=1; //月 18 int day=1; //日 19 int sum=0; 20 int k; 21 cout<<"\n请输入学生姓名(0退出 -1生成随机学生):";cin>>name; 22 if(name=="0")return 0; 23 else if(name=="-1") 24 { 25 cout<<"生成数量:";cin>>sum; 26 for(int i=1;i<=sum;i++) 27 { 28 name="abcdef"; 29 for(int j=6;j--;)name[j]=rand()%26+'a'; 30 sex=rand()%2?'M':'F'; 31 building=rand()%9+1; 32 room=(rand()%6+1)*100+rand()%12+1; 33 for(int j=11;--j;)number[j]=rand()%10+'0'; 34 for(int j=6;j--;)WeChat[j]=rand()%26+'a'; 35 for(int j=10;j--;)QQ[j]=rand()%10+'0'; 36 for(int j=6;j--;)stuid[j]=rand()%10+'0'; 37 for(int j=6;j--;)_class[j]=rand()%26+'a'; 38 year=rand()%6+1998; 39 mon=rand()%12+1; 40 day=rand()%28+1; 41 int cyc=nowday; 42 cout<<cyc<<endl; 43 stu.push_back(new student(name,sex,building,room,number,WeChat,QQ,stuid,_class,year,mon,day,cyc)); 44 cout<<"创建成功:"<<i<<endl; 45 } 46 save(stu,1); 47 } 48 else { 49 cout<<"性别(男M 女F):";cin>>sex; 50 cout<<"楼号 :";cin>>building; 51 cout<<"宿舍号 :";cin>>room; 52 cout<<"电话号码 :";cin>>number; 53 cout<<"微信号 :";cin>>WeChat; 54 cout<<"QQ :";cin>>QQ; 55 cout<<"学号 :";cin>>stuid; 56 cout<<"出生年 :";cin>>year; 57 cout<<"出生月 :";cin>>mon; 58 cout<<"出生日 :";cin>>day; 59 stu.push_back(new student(name,sex,building,room,number,WeChat,QQ,stuid,_class,year,mon,day,nowday)); 60 save(stu,1); 61 cout<<"成功!!!"; 62 } 63 cout<<"\n请继续(0返回 1继续添加)"; 64 while(k=getchar()){ 65 if(k=='0')return 0; 66 if(k=='1')return addstu(stu); 67 } 68 69 }
3。删除学生信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int delstu(vector<student*>&stu) //删除 del { system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 删除学生 |\n"; cout<<"+----------------------------------------------------------------+\n"; cout<<"请先通过搜索确定删除的同学(1总览)(2条件搜索)(3模糊搜索)(0返回)"<<endl; string k; vector<student*>stucyc; read(stucyc,2); for(cin>>k;k[0]<'0'||'3'<k[0];cin>>k) cout<<"输入错误!重新输入:"; if(k[0]=='0')return 0; if(k[0]=='1')allstu(stu,0); if(k[0]=='2')limisee(stu,0); if(k[0]=='3')see(stu,0); int p; while(1){ cout<<"请选择快捷编号(-1返回)(-2返回主菜单)(-3全删):"; cin>>p; if(p==-1)return delstu(stu); if(p==-2)return 0; if(p==-3){ stucyc.insert(stucyc.end(),stu.begin(),stu.end()); vector<student*>().swap(stu); save(stucyc,2); save(stu,1); cout<<"全部移动到回收站成功!!"; } int flag=-1; //是否存在 // int ij=0; //偏移量 // if(stu.size()!=0) //列表不为空下查找 // for(int low=0,high=stu.size()-1;low<=high;){ //二分法查找 // int mid=(low+high)/2; // if(stu[mid]->getkid()==p){flag=mid;break;} // else if(stu[mid]->getkid()<p) {low=mid+1;} // else high=mid-1; // } for(int i=0;i<stu.size();i++){ if(stu[i]->getkid()==p){flag=i;break;} } // for(;ij<stu.size();ij++) // if(stu[ij]->getkid()==p) // {flag=1;break;} if(flag<0)cout<<"无该学生\n"; else { // stu.erase(stu.begin()+flag); //原无回收站 stucyc.push_back(stu[flag]); save(stucyc,2); stu.erase(stu.begin()+flag); save(stu,1); cout<<"已移动到回收站!请继续~\n"; } } }
4 。模糊查询学生信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int see(vector<student*>&stu,int flag=1) //模糊查 { vector<student*>&p=stu; // int oo[p.size()]={0}; if(flag){ system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 模糊查询 |\n"; cout<<"+----------------------------------------------------------------+\n"; } cout<<"请输入学生任意信息:"; string ssn; cin>>ssn; for(int i=0;i<p.size();i++) { string ll[11]= { p[i]->getname(),p[i]->getnumber(), p[i]->getWeChat(),p[i]->getQQ(), p[i]->getstuid(),p[i]->get_class(), "","","","","" }; stringstream ss; //定义一个流来转换数字成字符 ss<<p[i]->getbuilding(); ss>>ll[6]; ss<<p[i]->getroom(); ss>>ll[7]; ss<<p[i]->getyear(); ss>>ll[8]; ss<<p[i]->getmon(); ss>>ll[9]; ss<<p[i]->getday(); ss>>ll[10]; for(int j=0;j<11;j++) //11个信息串 for(int y=0;ll[j][y];y++) //书串里的各个字符 for(int h=0;ssn[h];h++) //ssn里的字符 if(ll[j][y]==ssn[h]) p[i]->setoo(p[i]->getoo()+1); } // for(int k=p.size(),i=k;i--;) //运行 i伦 // for(int i=0;i<p.size();i++) // { // int max=0; //最大相关度下标 // for(int j=0;j<p.size();j++) // if(oo[max]<oo[j]) // max=j; // cout<<"\n相关度大小:"<<oo[max]<<endl; // p[max]->display(); // cout<<"\n"; // oo[max]=-1; // } /////////////////////////////////////////////////////// vector<student*>stu2=stu; sort(stu2.begin(),stu2.end(),comp); for(int i=0;i<stu2.size();i++) stu2[i]->display(); // for(std::vector<student*>::iterator m = vor.begin(); m != vor.end(); m++ ) //用迭代器的方式输出容器对象的值 // { // cout<<*m<<endl; //这里依次输出vector的值 // } if(flag){ cout<<"\n输入0返回:"; while(getchar()!=48); } }
5。回收站
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int recycle(vector<student*>&stu) //回收站 { system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 回收站 |\n"; cout<<"+----------------------------------------------------------------+\n"; vector<student*>stucyc; if(read(stucyc,2))cout<<"读取回收站文件错误!!";//read的功能2; cout<<"回收站总信息数:"<<stucyc.size()<<endl; for(int i=0;i<stucyc.size();i++){ cout<<"剩余保存时间:"<<cycsave-(nowday-stucyc[i]->getcyc())<<"次!\n"; stucyc[i]->display(); } cout<<"1<恢复一个> 2<删除一个> 3<全部删除> 4<全部恢复> 0<返回>"; string kin; cin>>kin; if(kin=="0")return 0; if(kin=="1"){ cout<<"请输入快捷编号:"; int kk; cin>>kk; int flag=-1; // if(stucyc.size()!=0)//列表不为空下查找 /////////////////////////////// // for(int low=0,high=stucyc.size()-1;low<=high;){ //二分法查找 // int mid=(low+high)/2; // if(stucyc[mid]->getkid()==kk){flag=mid;break;} // else if(stucyc[mid]->getkid()<kk) {low=mid+1;} // else high=mid-1; // } for(int i=0;i<stucyc.size();i++){ if(stucyc[i]->getkid()==kk){flag=i;break;} } if(flag<0){ cout<<"未找到!!!\n"; } else { stu.push_back(stucyc[flag]); save(stu,1); stucyc.erase(stucyc.begin()+flag); save(stucyc,2); cout<<"恢复成功"; } } if(kin=="2"){ cout<<"请输入快捷编号:"; int kk; cin>>kk; int flag=-1; // if(stucyc.size()!=0)//列表不为空下查找 // for(int low=0,high=stucyc.size()-1;low<=high;){ //二分法查找 // int mid=(low+high)/2; // if(stu[mid]->getkid()==kk){flag=mid;break;} // else if(stu[mid]->getkid()<kk) {low=mid+1;} // else high=mid-1; // } for(int i=0;i<stucyc.size();i++){ if(stucyc[i]->getkid()==kk){flag=i;break;} } if(flag<0){ cout<<"未找到!!!\n"; } else { delete stucyc[flag]; stucyc.erase(stucyc.begin()+flag); save(stucyc,2); cout<<"删除成功!\n"; } } if(kin=="3"){ for(int i=0;i<stucyc.size();i++){ delete stucyc[i]; //先清除new出来的数据 } vector<student*>().swap(stucyc); save(stucyc,2); cout<<"删除成功!!!\n"; } if(kin=="4"){ stu.insert(stu.end(),stucyc.begin(),stucyc.end()); vector<student*>().swap(stucyc); save(stu,1); save(stucyc,2); cout<<"恢复成功"; } cout<<"输入0返回"; while(getchar()!=48); for(int i=0;i<stucyc.size();i++){ delete stucyc[i]; } }
0)保存信息
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int save(vector<student*>&stu,int function=1) //save { ofstream stuout; if(function==1)stuout.open("student.txt",ios::out); //学生 if(function==2)stuout.open("student_recycle.txt",ios::out); //回收站 if(!stuout)return 1; stuout<<stu.size()<<endl; //先存总数 for(int i=0;i<stu.size();i++) { stuout<<stu[i]->name<<endl; stuout<<stu[i]->sex<<endl; stuout<<stu[i]->building<<endl; stuout<<stu[i]->room<<endl; stuout<<stu[i]->number<<endl; stuout<<stu[i]->WeChat<<endl; stuout<<stu[i]->QQ<<endl; stuout<<stu[i]->stuid<<endl; stuout<<stu[i]->_class<<endl; stuout<<stu[i]->year<<endl; stuout<<stu[i]->mon<<endl; stuout<<stu[i]->day<<endl; stuout<<stu[i]->cyc<<endl; //回收站 } stuout.close(); return 0; }
总结一下该程序主要用的一些技术:类、switch与case、指针、文件的读写。
3.我认为存在的缺陷
1.模糊查询存在错误
输入学生任意信息后,会显示全部学生的信息,达不到查询的目的。
2.缺少直接修改学生信息的功能,如果只输入部分信息错误,则需要全部删除后再添加,比较繁琐
3.除开完善模糊搜索以外,还可以添加条件搜索(即按照特定信息查找,如学号、姓名、电话号码等)。
二、 二次重开发后程序的介绍(代码较长只展示方法代码)
1.模糊搜索的完善
在原来的程序方法上,增加权重和相关度的概念,即输入查找样本,设置样本字母串的权重,所有学生信息的出现的样本字母串与权重积的总和,即为相关度,根据相关度的大小来确定获取所需要的信息。
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// //相同字符相应权重 //字符类型相应权重 int see2(vector<student*>&stu,vector<double>&weight_same,vector<double>&weight_information_tye,int flag=1) //模糊查 { // for(int i=0;i<weight_same.size();i++)cout<<weight_same[i]<<endl;/////////////////////// // for(int i=0;i<weight_information_tye.size();i++)cout<<weight_information_tye[i]<<endl; // while(getchar()!=48); vector<student*>&p=stu; double oo[p.size()]={0}; //相关度 if(flag){ system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 模糊+权重 |\n"; cout<<"+----------------------------------------------------------------+\n"; } cout<<"模糊搜索串数量:"; int sum_string; cin>>sum_string; string ssn[sum_string]; //输入的字符串 double weight_information_inter[sum_string]; //输入串相应的权重 for(int i=0;i<sum_string;i++){ cout<<"请输入学生任意信息+空格+该字符串权重:"; cin>>ssn[i]>>weight_information_inter[i]; // cout<<ssn[i]<<weight_information_inter[i]<<endl; ////////////////////// } for(int i=0;i<p.size();i++) //第 i 个学生 { string ll[11]= //保存学生信息串 { p[i]->getname(),p[i]->getnumber(), p[i]->getWeChat(),p[i]->getQQ(), p[i]->getstuid(),p[i]->get_class(), "","","","","" }; stringstream ss; //定义一个流来转换int数字信息成字符 ss<<p[i]->getbuilding(); ss>>ll[6]; ss<<p[i]->getroom(); ss>>ll[7]; ss<<p[i]->getyear(); ss>>ll[8]; ss<<p[i]->getmon(); ss>>ll[9]; ss<<p[i]->getday(); ss>>ll[10]; for(int j=0;j<11;j++) //11个学生信息串 j for(int ssni=0;ssni<sum_string;ssni++) //sum_string个输入串 ssni for(int h=0;ssn[ssni][h];h++) //ssn[ssni]里的字符 h for(int y=0;ll[j][y];y++){ //学生某信息串里的各个字符 y int sum=0; //字符后有多少字符相同 for(int h2=h,y2=y;ll[j][y2]==ssn[ssni][h2]&&ll[j][y2]&&ssn[ssni][h2];h2++,y2++) {sum++;} oo[i]+=weight_same[sum>weight_same.size()?weight_same.size()-1:sum]* weight_information_tye[j] * weight_information_inter[ssni]; } } // for(int k=p.size(),i=k;i--;) //运行 i伦 int oout[p.size()]={0}; //是否输出过 ? // for(int i=0;i<p.size();i++){ //测试 //////////////////////////////////// // cout<<oo[i]<<"\n"; // } for(int i=0;i<p.size();i++) //输出 { int min=-1; //最小相关度下标 for(int j=0;j<p.size();j++) { if(!oout[j]){ //找未输出过的 if(min==-1)min=j; //找到的未输出是否是第一个 else if(oo[min]>oo[j]){min=j;} } } cout<<"\n相关度大小:"<<oo[min]<<endl; p[min]->display(); cout<<"\n"; oout[min]=1; //标记输出过 } if(flag){ cout<<"\n输入0返回:"; while(getchar()!=48); } }
效果如图:
2.修改信息功能
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int modstu(vector<student*>&stu) { system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 修改学生信息 |\n"; cout<<"+----------------------------------------------------------------+\n"; cout<<"请先通过搜索查看同学编号(1总览)(2条件搜索)(3模糊搜索)(0返回)"<<endl; string k; for(cin>>k;k[0]<'0'||'3'<k[0];cin>>k) cout<<"输入错误!重新输入:"; if(k[0]=='0')return 0; if(k[0]=='1')allstu(stu,0); if(k[0]=='2')limisee(stu,0); if(k[0]=='3')see(stu,0); int p; while(1){ cout<<"请选择快捷编号(-1返回)(-2返回主菜单):"; cin>>p; if(p==-1)return delstu(stu); if(p==-2)return 0; int flag=-1; //是否存在 // int ij=0; // for(;ij<stu.size();ij++) //顺序查找 // if(stu[ij]->getkid()==p) // {flag=1;break;} // if(stu.size()!=0) //列表不为空下查找 // for(int low=0,high=stu.size()-1;low<=high;){ //二分法查找 // int mid=(low+high)/2; // if(stu[mid]->getkid()==p){flag=mid;break;} // else if(stu[mid]->getkid()<p) {low=mid+1;} // else high=mid-1; // } for(int i=0;i<stu.size();i++){ if(stu[i]->getkid()==p){flag=i;break;} } if(flag>=0){ int ij=flag; cout<<"该学生信息:"; stu[ij]->display(); cout<<"请选择需要修改的信息:\n"; string name="abcdef"; //名 char sex='M'; //性 int building=1; //楼 int room=506; //房 string number="12345678901"; //电话号码 string WeChat="123456"; //微信 string QQ="1234567890"; //QQ string stuid="2052538"; //学号 string _class="abcd01"; //班级 int year=2021; //年 int mon=1; //月 int day=1; //日 cout<<"姓名 :";cin>>name; cout<<"性别(男M 女F):";cin>>sex; cout<<"楼号 :";cin>>building; cout<<"宿舍号 :";cin>>room; cout<<"电话号码 :";cin>>number; cout<<"微信号 :";cin>>WeChat; cout<<"QQ :";cin>>QQ; cout<<"学号 :";cin>>stuid; cout<<"出生年 :";cin>>year; cout<<"出生月 :";cin>>mon; cout<<"出生日 :";cin>>day; stu[ij]->setname(name); stu[ij]->setsex(sex); stu[ij]->setbuilding(building); stu[ij]->setroom(room); stu[ij]->setnumber(number); stu[ij]->setWeChat(WeChat); stu[ij]->setQQ(QQ); stu[ij]->setstuid(stuid); stu[ij]->setyear(year); stu[ij]->setmon(mon); stu[ij]->setday(day); save(stu,1); // cout<<"修改成功!请继续修改:"; } else cout<<"无该学生\n"; } }
效果如图:
3.条件搜索
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int limisee(vector<student*>p,int flag=1) //条件搜索 { if(flag){ system("cls"); cout<<"+----------------------------------------------------------------+\n"; cout<<"| 条件筛选 |\n"; cout<<"+----------------------------------------------------------------+\n"; } cout<<"\n请输入筛选信息"; cout<<"1<姓氏> 2<性别> 3<楼号> 4<宿舍号> "<<endl; cout<<"5<出生年> 6<出生月> 7<出生日> 0<返回>"<<endl; int k; for(cin>>k;k<0||7<k;cin>>k) cout<<"输入错误!\n"; vector<student*>p2; if(k==0)return 0; if(k==1){ string ll; cout<<"请输入姓氏:"; cin>>ll; for(int i=0;i<p.size();i++){ string kk=p[i]->getname(); if(ll[0]==kk[0]){ p2.push_back(p[i]); } } } if(k==2){ cout<<"请选择男M 女F:"; string ll; cin>>ll; for(int i=0;i<p.size();i++){ char kk=p[i]->getsex(); if(ll[0]==kk){ p2.push_back(p[i]); } } } if(k==3){ cout<<"请输入楼号:"; int ll; cin>>ll; for(int i=0;i<p.size();i++){ int kk=p[i]->getbuilding(); if(ll==kk){ p2.push_back(p[i]); } } } if(k==4){ cout<<"请输入宿舍号:"; int ll; cin>>ll; for(int i=0;i<p.size();i++){ if(ll==p[i]->getroom()){ p2.push_back(p[i]); } } } if(k==5){ cout<<"请输入出生年:"; int ll; cin>>ll; for(int i=0;i<p.size();i++){ if(ll==p[i]->getyear()){ p2.push_back(p[i]); } } } if(k==6){ cout<<"请输入出生月:"; int ll; cin>>ll; for(int i=0;i<p.size();i++){ if(ll==p[i]->getmon()){ p2.push_back(p[i]); } } } if(k==7){ cout<<"请输入出生日:"; int ll; cin>>ll; for(int i=0;i<p.size();i++){ if(ll==p[i]->getday()){ p2.push_back(p[i]); } } } cout<<"共筛选出"<<p2.size()<<"个数据"<<endl; for(int i=0;i<p2.size();i++) p2[i]->display(); return limisee(p2,0); }
效果如图:
三、 感想
在经过了此次他人程序的二次开发后,我找到了几点在写代码时十分重要的点:
1.在写代码时,一定要加入注释,否则老师或同学在读代码时,会十分的麻烦,而且不仅仅是别人,甚至你自己过了很长一段时间后,再去看自己的代码,你自己都可能看不懂,所以写代码一定要写注释,写注释,写注释(重要的事情说三遍)!!!
2.此次修改他人的程序,让我认识到我对代码的阅读能力还有待提高,要提高阅读效率,可以节省不少时间。
3.在进行修改和插入代码部分时,过程还较为顺利,算是开了个好头,希望可以一直保持下去。