2013数据结构课程设计之通讯录(复习链表与文件知识)

来源:互联网 发布:大学校园电影网络电影 编辑:程序博客网 时间:2024/05/04 04:56

题目一  通讯录

[问题描述]

1) 通过键盘建立通讯录,每条记录至少包括2个数据项:姓名、电话号码;

2) 对通讯录进行插入、删除、修改和查找;

3) 通过姓名查找,必须实现精确查找和模糊查找,例如输入“张”,则显示第一个姓张的朋友,然后可以选择“下一个”,鼓励思路创新,提供其他多种查找方式,例如拼音查找等;

4) 也可以根据电话号码或部分电话号码进行精确查找和模糊查找;

5) 自行定义数据结构,可以选择性的将顺序查找、折半查找、索引查找、树型查找、哈希表等灵活运用其中,完成多方式查找功能。


感想:大一上结束的时候,老师要求做过学生管理系统,那时看见代码就挠头的我只能站在很低的位置仰慕那些做出来去找汪老师的人。自己当时一点也不会。当时到最后竟然连东西也没写,就那样放着放着就没了。现在多少会一点,虽然代码真的很屁,至少是昨天一晚上加今天早上的心血。凑合凑合吧。


解题思路:我直接写了一个主菜单menu,然后每次访问的时候就清屏,看起来很舒服。因为是链表,如果真的使用二分查找只能转换为数组方可。所以主菜单的6就是先对名字排序,然后7就是根据名字精确查找或模糊查找二分查找。8是根据电话号码精确查找或模糊查找,此处的模糊查找号码必须是前缀子串。9是根据关系精确查找。10是根据联系人地址模糊查找,此处的模糊查找只需要地址是子串即可。然后我每次查找的时候都会统计找到的人数!

选择11的话就把当前所有联系人保存到文件中,保存更改,选择12则不保存。

具体实现见代码与截屏。


代码:

#include<cstdio>#include<cstring>#include<cstdlib>#include<string>#include<iostream>using namespace std;int num;  //通讯录的总人数struct mq{    char name[50]; //名字    char tel[50];  //电话    char rela[50]; //关系,群组    char add[50];  //地址};mq node[1005];typedef struct notbook{    char name[50]; //名字    char tel[50];  //电话    char rela[50]; //关系,群组    char add[50];  //地址    struct notbook * next;} TEA;TEA *creat_list(TEA *head);  //建立通讯录void output_list(TEA *head); //输出所有联系人TEA *inser(TEA *head);  //添加联系人TEA *dele(TEA *head); //删除联系人TEA *update(TEA *head); //更改联系人信息TEA *namesort(TEA *head); //按照名字字典序排序void searchwithname(TEA *head); //按名字查找(二分查找)void searchwithtel(TEA *head);  //顺序精确+模糊必须是前缀串void searchwithrela(TEA *head); //顺序 精确void searchwithadd(TEA *head);  //顺序 模糊只要是子串即可int menu(void);int main(){    TEA *head,*p;    int falg,n;    char c;    FILE *fp;    head=NULL;    while(falg)    //菜单内容    {        n=menu();  //主显示屏        switch(n)        {        case 1:            head=creat_list(head);            printf("\n***成功建立联系人***   按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 2:            output_list(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 3:            head=inser(head);            printf("\n***成功添加联系人***   按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 4:            head=dele(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 5:            head=update(head);            printf("\n***成功更改联系人信息***   按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 6:            head=namesort(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 7:            searchwithname(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 8:            searchwithtel(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 9:            searchwithrela(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 10:            searchwithadd(head);            printf("\n按 0 返回主菜单!\n");            while((c=getchar()!='0'))                ;            break;        case 11:            if((fp=fopen("tongxunlu.txt","w"))==NULL)   //创建文件            {                printf("error in file!\n");                exit(-1);            }            fprintf(fp,"%d\n",num);            for(p=head; p!=NULL; p=p->next)  //把通讯录保存到文件            {                fprintf(fp,"%s\t%s\n%s\t%s\n",p->name,p->tel,p->rela,p->add);            }            falg=0;        default :            falg=0;        }    }    return 0;}TEA *creat_list(TEA *head)   //头插法创建链表{    TEA *p;    FILE *fp;  //打开文件    if((fp=fopen("tongxunlu.txt","r"))==NULL)   //以只读的方式打开文件    {        printf("error in file!\n");        exit(-1);    }    system("cls");  //清屏    head=NULL;    int i;    fscanf(fp,"%d",&num);    for(i=0; i<num; i++) //录入num个联系人    {        p=(TEA *)malloc(sizeof(TEA));  //输入的时候需要分配内存        fscanf(fp,"%s%s%s%s",p->name,p->tel,p->rela,p->add);        p->next=head;        head=p;    }    return head;}void output_list(TEA *head)  //输出所有联系人{    printf("***当前联系人共有:  %d人\n",num);    TEA *p;    p=head;    while(p!=NULL)    {        printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",p->name,p->tel,p->rela,p->add);        p=p->next;    }}TEA *inser(TEA *head)   //添加联系人{    TEA *p;    p=(TEA *)malloc(sizeof(TEA));    printf("请输入联系人的信息!!\n");    scanf("%s%s%s%s",p->name,p->tel,p->rela,p->add);    p->next=head;    head=p;    num++;    return head;}TEA *dele(TEA *head)  //删除联系人{    printf("请输入要删除联系人的名字!!\n");    char tmp[50];    scanf("%s",tmp);    int flag=0;    while(strcmp(head->name,tmp)==0&&head!=NULL)    {        head=head->next;        num--;        flag=1;    }    TEA *la,*p;    la=head,p=head->next;    while(p!=NULL)    {        if(strcmp(tmp,p->name)==0)        {            la->next=p->next;            p=p->next;            num--;            flag=1;        }        else        {            la=la->next;            p=p->next;        }    }    if(flag==0)        printf("\n***通讯录中还未添加此联系人\n");    else        printf("\n***成功删除联系人%s\n",tmp);    return head;}TEA *update(TEA *head)  //更改联系人{    TEA *q;    q=(TEA *)malloc(sizeof(TEA));    printf("请输入联系人的信息!!\n");    scanf("%s%s%s%s",q->name,q->tel,q->rela,q->add);    char tmp[50];    strcpy(tmp,q->name);    while(strcmp(head->name,tmp)==0&&head!=NULL)  //先删除联系人    {        head=head->next;        num--;    }    TEA *la,*p;    la=head,p=head->next;    while(p!=NULL)    {        if(strcmp(tmp,p->name)==0)        {            la->next=p->next;            p=p->next;            num--;        }        else        {            la=la->next;            p=p->next;        }    }    q->next=head;    head=q;    num++;    return head;}TEA *namesort(TEA *head)  //按名字排序{    TEA *head2,*p1,*p2,*t2;    head2=head;    head=head->next;    head2->next=NULL;  //先把第一个给head2    while(head!=NULL)    {        p2=head2;        p1=head;   //取出第一个联系人        head=head->next;        p1->next=NULL;        if(strcmp(p1->name,p2->name)<=0) //字典序最小        {            p1->next=p2;            head2=p1;            continue;        }        int flag=0;        while(p2->next!=NULL)        {            t2=p2->next;            if(strcmp(p1->name,t2->name)<=0)            {                p1->next=t2;                p2->next=p1;                flag=1;                break;            }            p2=p2->next;        }        if(!flag)   //字典序最大,插到最后面        {            p2->next=p1;        }    }    return head2;}void searchwithname(TEA *head)  //按名字二分查找{    int i;    int cnt=0;    TEA *p;    p=head;    for(i=0; i<num; i++)    {        strcpy(node[i].name,p->name),strcpy(node[i].tel,p->tel);        strcpy(node[i].tel,p->tel),strcpy(node[i].add,p->add);        p=p->next;    }    printf("***选择查找方式***\n\n");    printf("***按 1 精确查找\n");    printf("***按 2 模糊查找\n");    char sw[5];    scanf("%s",sw);    char tmp[50];    if(strcmp(sw,"1")==0)  //折半查找    {        printf("请输入联系人的名字\n");        scanf("%s",tmp);        int left,right,mid;        int res;        left=0,right=num-1;        while(left<right)        {            mid=(left+right)>>1;            if(strcmp(tmp,node[mid].name)==0)            {                res=mid;                break;            }            else if(strcmp(tmp,node[mid].name)<0)            {                right=mid-1;                res=right;            }            else if(strcmp(tmp,node[mid].name)>0)            {                left=mid+1;                res=left;            }        }        int l,r;        l=res-1>=0?res-1:0;        r=res+1<num?res+1:num-1;        if(strcmp(tmp,node[res].name)==0)        {            while(l>=0)            {                if(strcmp(tmp,node[l].name)==0)                {                    l--;                }                else                    break;            }            while(r<num)            {                if(strcmp(tmp,node[r].name)==0)                {                    r++;                }                else                    break;            }            if(strcmp(node[l].name,tmp)!=0)                l++;            if(strcmp(node[r].name,tmp)!=0)                r--;            cnt=r-l+1;        }        else            cnt=0;        if(cnt>0)        {            printf("***查找到的联系人共有: %d个人\n",cnt);            for(i=l; i<=r; i++)                printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",node[i].name,node[i].tel,node[i].rela,node[i].add);        }        else            printf("\n***您还未添加此联系人!!\n");    }    else if(strcmp(sw,"2")==0)    {        printf("请输入联系人的姓氏或者名字的前一部分\n");        scanf("%s",tmp);        int left,right,mid;        int res;        left=0,right=num-1;        int len=strlen(tmp);        while(left<right)        {            mid=(left+right)>>1;            if(strncmp(tmp,node[mid].name,len)==0)            {                res=mid;                break;            }            else if(strncmp(tmp,node[mid].name,len)<0)            {                right=mid-1;                res=right;            }            else if(strncmp(tmp,node[mid].name,len)>0)            {                left=mid+1;                res=left;            }        }        int l,r;        l=res-1>=0?res-1:0;        r=res+1<num?res+1:num-1;        if(strncmp(tmp,node[res].name,len)==0)        {            while(l>=0)            {                if(strncmp(tmp,node[l].name,len)==0)                {                    l--;                }                else                    break;            }            while(r<num)            {                if(strncmp(tmp,node[r].name,len)==0)                {                    r++;                }                else                    break;            }            if(strncmp(node[l].name,tmp,len)!=0)                l++;            if(strncmp(node[r].name,tmp,len)!=0)                r--;            cnt=r-l+1;        }        else            cnt=0;        if(cnt>0)        {            printf("***查找到的联系人共有: %d个人\n",cnt);            for(i=l; i<=r; i++)                printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",node[i].name,node[i].tel,node[i].rela,node[i].add);        }        else            printf("\n***您还未添加此联系人!!\n");    }}void searchwithtel(TEA *head){    int i;    int cnt=0;    TEA *p;    p=head;    mq tt[105];    printf("***选择查找方式***\n\n");    printf("***按 1 精确查找\n");    printf("***按 2 模糊查找\n");    char sw[5];    scanf("%s",sw);    char tmp[50];    if(strcmp(sw,"1")==0)    {        printf("请输入电话号码\n");        scanf("%s",tmp);        while(p!=NULL)        {            if(strcmp(p->tel,tmp)==0)            {                strcpy(tt[cnt].name,p->name),strcpy(tt[cnt].tel,p->tel);                strcpy(tt[cnt].rela,p->rela),strcpy(tt[cnt].add,p->add);                cnt++;            }            p=p->next;        }        if(cnt>0)        {            printf("***查找到的联系人共有: %d个人\n",cnt);            for(i=0; i<cnt; i++)                printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",tt[i].name,tt[i].tel,tt[i].rela,tt[i].add);        }        else            printf("\n***找不到联系人!!\n");    }    else if(strcmp(sw,"2")==0)    {        printf("请输入电话号码前几位\n");        scanf("%s",tmp);        int len=strlen(tmp);        while(p!=NULL)        {            if(strncmp(p->tel,tmp,len)==0)            {                strcpy(tt[cnt].name,p->name),strcpy(tt[cnt].tel,p->tel);                strcpy(tt[cnt].rela,p->rela),strcpy(tt[cnt].add,p->add);                cnt++;            }            p=p->next;        }        if(cnt>0)        {            printf("***查找到的联系人共有: %d个人\n",cnt);            for(i=0; i<cnt; i++)                printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",tt[i].name,tt[i].tel,tt[i].rela,tt[i].add);        }        else            printf("\n***找不到联系人!!\n");    }}void searchwithrela(TEA *head){    int i;    int cnt=0;    TEA *p;    p=head;    mq tt[105];    printf("请输入关系:\n");    char tmp[50];    scanf("%s",tmp);    while(p!=NULL)    {        if(strcmp(p->rela,tmp)==0)        {            strcpy(tt[cnt].name,p->name),strcpy(tt[cnt].tel,p->tel);            strcpy(tt[cnt].rela,p->rela),strcpy(tt[cnt].add,p->add);            cnt++;        }        p=p->next;    }    if(cnt>0)    {        printf("***查找到的联系人共有: %d个人\n",cnt);        for(i=0; i<cnt; i++)            printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",tt[i].name,tt[i].tel,tt[i].rela,tt[i].add);    }    else        printf("\n***找不到联系人!!\n");}void searchwithadd(TEA *head)   //模糊查找,只需要是子串即可{    int i,j;    int cnt=0;    TEA *p;    p=head;    mq tt[105];    printf("请输入地址:\n");    char tmp[50];    scanf("%s",tmp);    char s[50];    int len1=strlen(tmp);    while(p!=NULL)    {        int len2=strlen(p->add);        int flag=0;        if(len2>=len1)        {            int mo=len2-len1;            for(i=0;i<=mo;i++)            {                for(j=i;j<len1+i;j++)                {                    s[j-i]=p->add[j];                }                s[len1]='\0';                if(strcmp(s,tmp)==0)                {                    flag=1;                    break;                }            }        }        if(flag)        {            strcpy(tt[cnt].name,p->name),strcpy(tt[cnt].tel,p->tel);            strcpy(tt[cnt].rela,p->rela),strcpy(tt[cnt].add,p->add);            cnt++;        }        p=p->next;    }    if(cnt>0)    {        printf("***查找到的联系人共有: %d个人\n",cnt);        for(i=0; i<cnt; i++)            printf("姓名:%s\t电话:%s\n关系:%s\t地址:%s\n\n",tt[i].name,tt[i].tel,tt[i].rela,tt[i].add);    }    else        printf("\n***找不到联系人!!\n");}int menu(void){    int n;    system("cls");   //清屏    //显示主屏    printf("***欢迎来到本通讯录管理系统***\n\n");    printf("温馨提示: 请按下面的数字键获取相应服务\n\n");    printf("****1.\t创 建 通 讯 录\n");    printf("****2.\t输 出 所 有 联 系 人\n");    printf("****3.\t添 加 联 系 人\n");    printf("****4.\t删 除 联 系 人\n");    printf("****5.\t更 改 联 系 人\n");    printf("****6.\t按 名 字 排 序\n");    printf("****7.\t按 名 字 查 找\n");    printf("****8.\t按 电 话 查 找\n");    printf("****9.\t按 关 系 查 找\n");    printf("***10.\t按 地 址 查 找\n");    printf("***11.\t保 存 结 果 并 退 出 通 讯 录 系 统\n");    printf("***12.\t不 保 存 结 果 并 退 出 通 讯 录 系 统\n");    printf("***欢迎来到本通讯录管理系统***\n");    scanf("%d",&n);    system("cls");  //再次清屏    return n;}/*孙悟空1872323220偶像中国武汉于果1902345645死党中国北京tongxunlu.txt内容:12mother13972083438亲人襄阳浩哥15671628522同学武科大酒井法子456713偶像日本茂茂15671628131同学武科大莫莫202020同学武科大少佳13145673214哥们儿武汉长江工商小凡1804920282死党北京张国荣13145675678偶像北京张国荣13145671234偶像北京张三911死党大武汉张小敏1782345180同学武汉中南财经周璇18064109632哥们儿武汉中医*/










我去,忘记用strstr来判断子串了。。。。