您的位置:首页 > 其它

【软件开发综合实验】电话号码本

2017-11-23 21:13 337 查看
#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;
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐