【软件开发综合实验】电话号码本
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<list> #include<conio.h> #include<windows.h> using namespace std; typedef unsigned long long ull; const int MOD=1009; const ull base=131; struct data{ string name,tel,add; data(const string &name,const string &tel,const string &add){ this->name=name; this->tel=tel; this->add=add; } data(const char* name,const char* tel,const char* add){ this->name=name; this->tel=tel; this->add=add; } data(){} }; typedef list<data>::iterator ITER; bool type; list<data>L[2][MOD]; data H[2][MOD]; bool Full[2][MOD]; int sz; ull GetHkey(const string &s); int SearchHTable_name(const string &name);//返回所查找姓名在哈希表中的下标,如该姓名不存在,返回-1 int SearchHTable_tel(const string &tel);//返回所查找电话号码在哈希表中的下标,如该电话号码不存在,返回-1 bool InsertHTable(const data &man); bool DeleteHTable(const string &name); void CreateHTable(const bool &op);//op为0 链地址法; op为1 开放地址法+线性探测再散列 void DisplayHTable(); int main(){ int opt; printf("\n\n\t\t欢迎使用电话簿!请您先选择合适的哈希方式!\n"); printf("\n\t\t请输入选项前的数字进行选择\n"); printf("\n\t\t1. 链地址法\n"); printf("\n\t\t2. 开放地址法 + 线性探测再散列\n"); printf("\n\t\t"); scanf("%d",&opt); CreateHTable((bool)(opt-1)); while(1){ system("cls"); printf("\n\n\t\t您正在使用基于"); if(!type){ printf(" 链地址法 "); } else{ printf(" 开放地址法 + 线性探测再散列 "); } printf("的电话簿,请选择您想使用的功能!\n"); printf("\n\t\t1. 向电话簿中插入一个人的信息\n"); printf("\n\t\t2. 根据输入的姓名查询其完整信息\n"); printf("\n\t\t3. 根据输入的电话号码查询其完整信息\n"); printf("\n\t\t4. 删除一个已存在的人的信息\n"); printf("\n\t\t5. 展示完整的电话簿\n"); printf("\n\t\t6. 将当前电话簿保存到文件\n"); printf("\n\t\t7. 退出\n"); printf("\n\t\t"); scanf("%d",&opt); if(opt==1){ string Name,Tel,Add; system("cls"); printf("\n\n\t\t请依次键入姓名 电话号码 住址(以空格分隔)!\n\n\t\t"); cin>>Name>>Tel>>Add; if(Name.length()>20 || Tel.length()>15 || Add.length()>50){ printf("\n\n\t\t输入不合法,插入失败!"); } else if(InsertHTable(data(Name,Tel,Add))){ printf("\n\n\t\t插入成功!"); } else{ if(sz==MOD){ printf("\n\n\t\t电话簿已满,插入失败!"); } else{ printf("\n\n\t\t已存在,插入失败!"); } } } else if(opt==2){ string Name; system("cls"); printf("\n\n\t\t请键入姓名!\n\n\t\t"); cin>>Name; int p; if((p=SearchHTable_name(Name))!=-1){ printf("\n\t\t姓名 电话号码 住址"); if(!type){ for(ITER it=L[0][p].begin();it!=L[0][p].end();++it){ if(it->name==Name){ cout<<"\n\n\t\t"<<it->name<<' '<<it->tel<<' '<<it->add; break; } } } else{ cout<<"\n\n\t\t"<<H[0][p].name<<' '<<H[0][p].tel<<' '<<H[0][p].add; } } else{ printf("\n\n\t\t您要查找的姓名不存在!"); } } else if(opt==3){ string Tel; system("cls"); printf("\n\n\t\t请键入电话号码!\n\n\t\t"); cin>>Tel; int p; if((p=SearchHTable_tel(Tel))!=-1){ printf("\n\t\t姓名 电话号码 住址"); if(!type){ for(ITER it=L[1][p].begin();it!=L[1][p].end();++it){ if(it->tel==Tel){ cout<<"\n\n\t\t"<<it->name<<' '<<it->tel<<' '<<it->add; break; } } } else{ cout<<"\n\n\t\t"<<H[1][p].name<<' '<<H[1][p].tel<<' '<<H[1][p].add; } } else{ printf("\n\n\t\t您要查找的电话号码不存在!"); } } else if(opt==4){ string Name; system("cls"); printf("\n\n\t\t请键入要删除的人的姓名!\n\n\t\t"); cin>>Name; int p; if(DeleteHTable(Name)){ printf("\n\n\t\t删除成功!"); } else{ printf("\n\n\t\t您要删除的姓名不存在!"); } } else if(opt==5){ DisplayHTable(); } else if(opt==6){ system("cls"); printf("\n\n\t\t保存成功!"); FILE *fp=fopen("TELETABLE.txt","w"); if(!type){ for(int i=0;i<MOD;++i){ for(ITER it=L[0][i].begin();it!=L[0][i].end();++it){ fprintf(fp,"%s %s %s\n",(it->name).c_str(),(it->tel).c_str(),(it->add).c_str()); } } } else{ for(int i=0;i<MOD;++i){ if(Full[0][i]){ fprintf(fp,"%s %s %s\n",(H[0][i].name).c_str(),(H[0][i].tel).c_str(),(H[0][i].add).c_str()); } } } fclose(fp); } else{ return 0; } printf("\n\n\t\t按任意键返回主菜单!"); while(!kbhit()); getch(); } return 0; } ull GetHkey(const string &s){ int len=s.length(); ull hs=0; for(int i=0;i<len;++i){ hs=hs*base+s[i]; } return hs; } int SearchHTable_name(const string &name){ ull hs=GetHkey(name); int U=(int)(hs%(ull)MOD); if(!type){ for(ITER it=L[0][U].begin();it!=L[0][U].end();++it){ if(it->name==name){ return U; } } return -1; } else{ for(int i=U;i!=(U-1+MOD)%MOD;i=(i+1)%MOD){ if(!Full[0][i]){ return -1; } if(H[0][i].name==name){ return i; } } return -1; } } int SearchHTable_tel(const string &tel){ ull hs=GetHkey(tel); int U=(int)(hs%(ull)MOD); if(!type){ for(ITER it=L[1][U].begin();it!=L[1][U].end();++it){ if(it->tel==tel){ return U; } } return -1; } else{ for(int i=U;i!=(U-1+MOD)%MOD;i=(i+1)%MOD){ if(!Full[1][i]){ return -1; } if(H[1][i].tel==tel){ return i; } } return -1; } } bool InsertHTable(const data &man){ if(sz==MOD || SearchHTable_name(man.name)!=-1){ return false; } ++sz; int U[2]; U[0]=(int)(GetHkey(man.name)%(ull)MOD); U[1]=(int)(GetHkey(man.tel)%(ull)MOD); if(!type){ for(int i=0;i<=1;++i){ L[i][U[i]].push_back(man); } } else{ for(int i=0;i<=1;++i){ for(int j=U[i];j!=(U[i]-1+MOD)%MOD;j=(j+1)%MOD){ if(!Full[i][j]){ H[i][j]=man; Full[i][j]=true; break; } } } } return true; } bool DeleteHTable(const string &name){ int p[2]; p[0]=SearchHTable_name(name); if(p[0]==-1){ return false; } string tel; if(!type){ for(ITER it=L[0][p[0]].begin();it!=L[0][p[0]].end();++it){ if(it->name==name){ tel=it->tel; break; } } } else{ tel=H[0][p[0]].tel; } p[1]=SearchHTable_tel(tel); if(!type){ for(int i=0;i<=1;++i){ for(ITER it=L[i][p[i]].begin();it!=L[i][p[i]].end();++it){ if(it->name==name){ L[i][p[i]].erase(it); break; } } } } else{ Full[0][p[0]]=Full[1][p[1]]=false; } return true; } void CreateHTable(const bool &op){ type=op; sz=0; if(!op){ for(int i=0;i<=1;++i){ for(int j=0;j<MOD;++j){ L[i][j].clear(); } } } else{ memset(Full,0,sizeof(Full)); } FILE *fp=fopen("TELETABLE.txt","r"); char tname[21],ttel[16],tadd[51]; while(fscanf(fp,"%s%s%s",tname,ttel,tadd)!=EOF){ InsertHTable(data(tname,ttel,tadd)); } fclose(fp); } void DisplayHTable(){ system("cls"); printf("\n\t\t姓名 电话号码 住址\n"); if(!type){ for(int i=0;i<MOD;++i){ for(ITER it=L[0][i].begin();it!=L[0][i].end();++it){ cout<<"\n\t\t"<<it->name<<' '<<it->tel<<' '<<it->add<<endl; } } } else{ for(int i=0;i<MOD;++i){ if(Full[0][i]){ cout<<"\n\t\t"<<H[0][i].name<<' '<<H[0][i].tel<<' '<<H[0][i].add<<endl; } } } }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/