现在的位置: 首页 > 综合 > 正文

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

2013年10月14日 ⁄ 综合 ⁄ 共 9381字 ⁄ 字号 评论关闭

题目一  通讯录

[问题描述]

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内容:
12
mother	13972083438
亲人	襄阳
浩哥	15671628522
同学	武科大
酒井法子	456713
偶像	日本
茂茂	15671628131
同学	武科大
莫莫	202020
同学	武科大
少佳	13145673214
哥们儿	武汉长江工商
小凡	1804920282
死党	北京
张国荣	13145675678
偶像	北京
张国荣	13145671234
偶像	北京
张三	911
死党	大武汉
张小敏	1782345180
同学	武汉中南财经
周璇	18064109632
哥们儿	武汉中医
*/









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

 

抱歉!评论已关闭.