BUAA数据结构第二次作业题解——通讯录整理

【问题描述】

读取一组电话号码簿(由姓名和手机号码组成),将重复出现的项删除(姓名和电话号码都相同的项为重复项,只保留第一次出现的项),并对姓名相同手机号码不同的项进行如下整理:首次出现的项不作处理,第一次重复的姓名后面加英文下划线字符_和数字1,第二次重复的姓名后面加英文下划线字符_和数字2,依次类推。号码簿中姓名相同的项数最多不超过10个。最后对整理后的电话号码簿按照姓名进行从小到大排序,并输出排序后的电话号码簿。

【输入形式】

先从标准输入读取电话号码个数,然后分行输入姓名和电话号码,姓名由不超过20个英文小写字母组成,电话号码由11位数字字符组成,姓名和电话号码之间以一个空格分隔,输入的姓名和电话号码项不超过100个。

【输出形式】

按照姓名从小到大的顺序分行输出最终的排序结果,先输出姓名再输出电话号码,以一个空格分隔。

【样例输入】

15

liping 13512345678

zhaohong 13838929457

qiansan 13900223399

zhouhao 18578294857

anhai 13573948758

liping 13512345678

zhaohong 13588339922

liping 13833220099

boliang 15033778877

zhaohong 13838922222

tianyang 18987283746

sunnan 13599882764

zhaohong 13099228475

liushifeng 13874763899

caibiao 13923567890

【样例输出】

anhai 13573948758

boliang 15033778877

caibiao 13923567890

liping 13512345678

liping_1 13833220099

liushifeng 13874763899

qiansan 13900223399

sunnan 13599882764

tianyang 18987283746

zhaohong 13838929457

zhaohong_1 13588339922

zhaohong_2 13838922222

zhaohong_3 13099228475

zhouhao 18578294857

【样例说明】

输入了15个人名和电话号码。其中第一项和第六项完全相同,都是“liping 13512345678”,将第六项删除,第一项保留;

第八项和第一项人名相同,电话不同,则将第八项的人名整理为liping_1;同样,第二项、第七项、第十项、第十三项的人名都相同,将后面三项的人名分别整理为:zhaohong_1、zhaohong_2和zhaohong_3。

最后将整理后的电话簿按照姓名进行从小到大排序,分行输出排序结果。

【评分标准】

该题要求编程实现通讯录的整理与排序,提交程序文件名为sort.c。

【思路】
1.建立结构体数组(没学过的同学可以去了解一下),读入姓名与电话号
2.结构体qsort排序,之后遍历使用strcmp函数对比即可,利用结构体数组中的times标记判断'_'之后应该加的数字,可以将重复的内容用strcpy将姓名标记为“-1”,输出时判断即可
 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct s1{
	char name[30];
	char number[30];
	int times;
}s1;

s1 Te[120];

int cmp(const void *a,const void*b)
{
	return strcmp(((struct s1*)a)->name,((struct s1*)b)->name);
} 


int main()
{
	int len; 
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%s %s",Te[i].name,Te[i].number);
		Te[i].times=0;
	}
	qsort(Te,n,sizeof(struct s1),cmp);
	
	for(int i=0;i<n;i++)
	{
		len=strlen(Te[i].name);
		for(int x=0;x<i;x++)//逐个遍历 
		{
			if(strcmp(Te[x].name,"-1")!=0)
			{
			if((strcmp(Te[i].name,Te[x].name)==0)&&(strcmp(Te[i].number,Te[x].number)==0))//判断相同 
			{
				strcpy(Te[i].name,"-1");
				break;
			}
			else if((strcmp(Te[i].name,Te[x].name)==0)&&(strcmp(Te[i].number,Te[x].number)!=0))
			{
				Te[i].times++;	//不同时次数加1标记_后出现的数字 
			}
			}
		}
	}
		
	for(int i=0;i<n;i++)//遍历输出 
	{
		if(strcmp(Te[i].name,"-1")!=0&&Te[i].times==0)
		{
			printf("%s %s\n",Te[i].name,Te[i].number);
		}
		else if(strcmp(Te[i].name,"-1")!=0&&Te[i].times!=0)
		{
			printf("%s_%d %s\n",Te[i].name,Te[i].times,Te[i].number);
		}
	}	
	
	
	return 0;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值