统计电话号码

统计电话号码

企业喜欢用容易被记住的电话号码。让电话号码容易被记住的一个办法是将它写成一个容易记住的单词或者短语。例如,你需要给Waterloo大学打电话时,可以拨打TUT-GLOP。有时,只将电话号码中部分数字拼写成单词。当你晚上回到酒店,可以通过拨打310-GINO来向Gino’s订一份pizza。让电话号码容易被记住的另一个办法是以一种好记的方式对号码的数字进行分组。通过拨打Pizza Hut的“三个十”号码3-10-10-10,你可以从他们那里订pizza。
电话号码的标准格式是七位十进制数,并在第三、第四位数字之间有一个连接符。电话拨号盘提供了从字母到数字的映射,映射关系如下: A, B, 和C 映射到 2 D, E, 和F 映射到 3 G, H, 和I 映射到 4 J, K, 和L 映射到 5 M, N, 和O 映射到 6 P, R, 和S 映射到 7 T, U, 和V 映射到 8 W, X, 和Y 映射到 9 Q和Z没有映射到任何数字,连字符不需要拨号,可以任意添加和删除。 TUT-GLOP的标准格式是888-4567,310-GINO的标准格式是310-4466,3-10-10-10的标准格式是310-1010。 如果两个号码有相同的标准格式,那么他们就是等同的(相同的拨号)
你的公司正在为本地的公司编写一个电话号码薄。作为质量控制的一部分,你想要检查是否有两个和多个公司拥有相同的电话号码。
输入:输入的格式是,第一行是一个正整数,指定电话号码薄中号码的数量(最多100000)。余下的每行是一个电话号码。每个电话号码由数字,大写字母(除了Q和Z)以及连接符组成
输出:对于每个出现重复的号码产生一行输出,输出是号码的标准格式紧跟一个空格然后是它的重复次数。如果存在多个重复的号码按照号码的字典升序输出。如果没有重复的号码,输出一行:
No duplicates.

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 char map[]="22233344455566677778889999";  //Q和Z先正常考虑,如若不考虑,对应关系就会受到影响。
 char str[80],telNumbers[100000][9];
 int compare(const void *elem1,const void *elem2)  //const修饰指向的对象,A可变,A指向的对象不可变
 	 //为函数模板sort定义数组元素的比较函数 
 {
 	 return(strcmp((char*)elem1,(char*)elem2)); 
 };
 void standardizeTel(int n)//是一个函数,使标准化,规格化 。简洁易读。
 {
 	int j,k; 	
 	j=k=-1;//... 
 	while(k<8)
 	{
 		j++;
		 if(str[j]=='-')	
 			continue;
 		k++;
 		if(k==3)
 		{
 			telNumbers[n][k]='-';
 			k++;
		 }
		 if(str[j]>='A'&&str[j]<='Z') 
		 {
		 	telNumbers[n][k]=map[str[j]-'A'];
		 	continue;
		 };
		 telNumbers[n][k]=str[j];	
	} 
	telNumbers[n][k]='\0';
	return;
 }
 int main()
 {
 	int n,j,i;
 	bool noduplicate;
 	
 	scanf("%d",&n);
 	for(i=0;i<n;i++)	//输入电话号码,储存到数组telNumbers中
 	{
		 scanf("%s",str);
		 standardizeTel(i);//将str中的电话号码转化成标准形式 ,储存在telNumbers中第i行 
	 }
	 qsort(telNumbers,n,9,compare);//对输入的电话号码进行排序
	  noduplicate=true;//对布尔变量赋值true 
	  i=0;
	  while(i<n)//搜索重复的电话号码,并进行输出
	  {	 
	   j=i;//j用来记录原来的位置 
	  i++;
	  while(i<n&&strcmp(telNumbers[i],telNumbers[j])==0) i++;//相邻的比较,相同则i加一,此时是已经排序了的
	  if(i-j>1)  //大于1说明存在相同的两行 
	  {
	  	printf("%s%d\n",telNumbers[j],i-j);
		noduplicate=false;
	   } 	
	   } 
	 if(noduplicate) printf("No duplicates.\n");
}

分析
(1)判断输入的电话号码中是否有重复号码:将各种电话号码表示转换成标准表示:一个长度为 8 的字符串,前三个字符是数字、第 4 个字符是’-’、后四个字符是数字。
(2)用一个二维数组 telNumbers[100000][9]来存储全部的电话号码,每一行存储一个电话号码
的标准表示。每读入一个电话号码,首先将其转换成标准表示,然后存储到二维数组
telNumbers 中。
(3) telNumbers 为一个一维数组,其中每个元素是一个字符串,用C/C++提供的函数模板sort对进行排序。用字符串比较函数strcmp比较 telNumbers 中相邻的电话号码,判断是否有重复的电话号码、并计算重复的次数。
总结
(1)首先这道题题目较长,需要仔细分析找出关键点。其次,问题涉及的字符较多,形式较多,需要考虑如何转换更加方便清晰。
(2)解决这个问题,所要运用的函数较多。由于初学,需要了解的也多。
sort() 定义在在头文件< algorithm>中。sort函数是标准模板库的函数,已知开始和结束的地址即可进行排序,可以用于比较任何容器(必须满足随机迭代器),任何元素,任何条件,执行速度一般比qsort要快,相当于它的升级版。另外,sort()是类属函数,可以用于比较任何容器,任何元素,任何条件。
int compare(const void * elem1,const void * elem2) 是qsort的比较函数。
strcmp() 也是比较函数。
**standardize()**使程序结构简洁清晰。

猜你喜欢

转载自blog.csdn.net/m0_45128748/article/details/91781237