【问题描述】
给定一已按姓名有序(字典升序)的通信录,通讯录中包括每个联系人的姓名(由英文字符组成,不含空格,并且字符个数不超过20,不会出现姓名相同的两个联系人)及电话(由11位数字字符组成),在该通信录中查找某人,如果姓名存在,且电话与给定的电话不一致,则更新该人电话;如果某人姓名不存在,则将该人的通信方式加到通信录中,更新后的通信录仍有序;如果姓名电话都一致,则不作任何修改。
要求:用折半查找算法进行查找,并输出每次折半查找时比较的位置信息。
【输入形式】
先从标准输入读入通信录中联系人的人数(大于等于1,小于等于100),然后分行输入联系人的姓名和电话,并在最后一行输入待查找的人的姓名和电话,姓名和电话都以一个空格分隔。
【输出形式】
先在一行上输出折半查找时每次比较的位置信息(联系人在通信录中的位置从0开始计数),各位置信息之间以一个空格分隔,最后一个位置信息后也有一个空格;然后在下一行输出维护操作信息(Found的第一个大写字母F表示找到了姓名和电话都一致的联系人;Update的第一个大写字母U表示找到了姓名一致的联系人,但电话不同需要更新;Insert的第一个大写字母I表示找不到姓名一致的联系人,需要添加该联系人)和位置信息(F和U后的位置信息表示该联系人在通信录中的位置;I后的位置信息表示插入后该人在通信录中的位置),更新字符信息和位置信息之间以一个空格分隔。
【样例输入1】
10
alice 13912345678
anne 13875695623
betty 13575699852
bob 13655662233
candy 18925639871
diego 13956231572
eva 13517635412
henry 13596853217
isabella 13815623698
matthew 18956712389
diego 13955668899
【样例输出1】
4 7 5
U 5
【样例说明1】
按照字典升序输入了10个人的姓名和电话,待查找人的姓名为diego,第一次折半查找比较的位置为4(位置0和9的中间位置),diego比candy大,则继续在位置5和9之间查找;第二次折半查找比较的位置为7,diego比henry小,则继续在位置5和6之间查找;第三次折半查找比较的位置为5,找到了姓名为diego的联系人,但电话不一致,需要更新电话,所以输出更新操作信息U和位置信息5。
【样例输入2】
10
alice 13912345678
anne 13875695623
betty 13575699852
bob 13655662233
candy 18925639871
diego 13956231572
eva 13517635412
henry 13596853217
isabella 13815623698
matthew 18956712389
dieg 13955668899
【样例输出2】
4 7 5
I 5
【样例说明2】
按照字典升序输入了10个人的姓名和电话,待查找人的姓名为dieg,每次比较的位置信息同样例1,但第三次比较后dieg小于diego,因此更改折半查找的起始位置和终止位置为5和4,起始位置大于终止位置,查找失败,需要插入待查找人的信息,插入的位置为5,所以输出I和5。
【样例输入3】
10
alice 13912345678
anne 13875695623
betty 13575699852
bob 13655662233
candy 18925639871
diego 13956231572
eva 13517635412
henry 13596853217
isabella 13815623698
matthew 18956712389
matthew 18956712389
【样例输出3】
4 7 8 9
F 9
【样例说明1】
按照字典升序输入了10个人的姓名和电话,待查找人的姓名为matthew,经过四次比较最终找到了联系人,并且电话信息也相同,所以最后输出F和9。
【评分标准】
该题要求查找更新通信录,提交的文件名为:find.c
我的代码:
#include <stdio.h>
#include <string.h>
#define MAXN 30
typedef struct person
{
char name[MAXN];
char tel[12];
} Person;
int main()
{
int n;
scanf("%d\n",&n);
Person persons[n];
Person s;
for(int i=0;i<n;++i)
{
scanf("%s %s",persons[i].name,persons[i].tel);
}
scanf("%s %s",s.name,s.tel);
int l=0,h=n-1,m;
while(1)
{
if(l>h) break;
m=(l+h)/2;
printf("%d ",m);
if(strcmp(persons[m].name,s.name)==0) break;
else if(strcmp(persons[m].name,s.name)<0) l=m+1;
else h=m-1;
}
if(l<=h && (strcmp(persons[m].tel,s.tel)))
{
printf("\nU %d",m);
// strcpy(persons[m].tel,s.tel);
}
else if(l>h)
{
if(strcmp(persons[m].name,s.name)<0) printf("\nI %d",m+1);
else printf("\nI %d",m);
}
else printf("\nF %d",m);
return 0;
}
测试结果: