2013資料結構課程設計之通訊錄(複習連結串列與檔案知識)
題目一 通訊錄
[問題描述]
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來判斷子串了。。。。
相關文章
- JavaScript資料結構之連結串列--設計JavaScript資料結構
- 資料結構之「連結串列」資料結構
- 資料結構之連結串列資料結構
- 資料結構與演算法知識點總結(1)陣列與連結串列資料結構演算法陣列
- 資料結構學習--連結串列資料結構
- JavaScript資料結構 之 連結串列JavaScript資料結構
- 資料結構之連結串列【上】資料結構
- 資料結構之連結串列操作資料結構
- JAVA資料結構之連結串列Java資料結構
- 資料結構之單連結串列資料結構
- 資料結構課程設計報告——暢通工程資料結構
- 資料結構之迴圈連結串列資料結構
- 資料結構之雙向連結串列資料結構
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 資料結構實驗之連結串列二:逆序建立連結串列資料結構
- 資料結構實驗之連結串列七:單連結串列中重複元素的刪除資料結構
- Redis資料結構—連結串列與字典Redis資料結構
- 資料結構-連結串列資料結構
- 資料結構 - 連結串列資料結構
- 連結串列-資料結構資料結構
- 資料結構--連結串列資料結構
- 資料結構—連結串列資料結構
- Redis資料結構—連結串列與字典的結構Redis資料結構
- 資料結構與演算法學習-連結串列上資料結構演算法
- 資料結構與演算法學習-連結串列下資料結構演算法
- 資料結構實驗之連結串列三:連結串列的逆置資料結構
- 資料結構實驗之連結串列五:單連結串列的拆分資料結構
- 資料結構實驗之連結串列六:有序連結串列的建立資料結構
- 資料結構實驗之連結串列一:順序建立連結串列資料結構
- 資料結構之連結串列篇(單連結串列的常見操作)資料結構
- 資料結構之連結串列:206. 反轉連結串列資料結構
- 03 Javascript資料結構與演算法 之 連結串列JavaScript資料結構演算法
- 資料結構之單連結串列的建立與刪除資料結構
- 資料結構之連結串列與陣列(1):陣列和連結串列的簡介資料結構陣列
- 資料結構-單連結串列、雙連結串列資料結構
- 學習 JavaScript 資料結構(二)——連結串列JavaScript資料結構
- 學習 JS 資料結構(2):連結串列JS資料結構
- Redis基礎資料結構之連結串列Redis資料結構