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

#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;
            }
        }
    }
}
posted @ 2017-11-23 21:13  AutSky_JadeK  阅读(204)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト