2013資料結構課程設計之通訊錄(複習連結串列與檔案知識)

果7發表於2013-09-18

題目一  通訊錄

[問題描述]

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來判斷子串了。。。。

 

相關文章