题目:为了更好地记忆电话号码,将数字转换成大写英文字母,字母与数字对应关系如下:
A, B, and C map to 2
D, E, and F map to 3
G, H, and I map to 4
J, K, and L map to 5
M, N, and O map to 6
P, R, and S map to 7
T, U, and V map to 8
W, X, and Y map to 9
电话号码的标准格式是7位数字,第3位和第4位之间用‘-’隔开,如888-4567。方便记忆的电话号码如TUT-GLOP对应的标准格式是888-4567。输入一系列方便记忆的电话号码,输出出现两次以上的电话号码的标准格式,输出按字典序排序。如果没有重复出现的电话号码,则输出 No duplicates.
输入:
第一行输入电话号码的个数,第二行开始输入电话号码,每个电话号码占一行,输入的电话号码由大写字母、数字和‘-’组成。
输出:
输出重复出现两次及以上的电话号码的标准格式,输出的电话号码按字典序排序。如果没有重复则输出No duplicates.
解题思路:
1 将电话号码转换成整数,则范围为0~9999999,因为范围已知,可以采用桶排序,开辟一个大小为10000000的数组A作为桶,初始化内容为0。
2 先将输入的电话号码转换成7位的整数,设为i,将A[i]的值加1。
3 输入结束后,扫描数组A,如果A[i]大于等于2,则输出i和A[i], i是电话号码,A[i]是电话号码出现的次数。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
char getDigit(char ch)
{
char num;
if(ch<='9' && ch>='0') return ch-'0';
num = ch-'A';
if(num > 15) num--;
return num/3 + 2;
}
int transform(char s[])
{
int i,result=0;
for(i=0; i<256; i++)
{
if(s[i]=='\0') break;
if(s[i] != '-') result = result*10 + getDigit(s[i]);
}
return result;
}
void print(int a, int count)
{
int i=0;
int base=1000000;
char s[9];
s[3]='-';
s[8]='\0';
for(;i<8;i++)
{
if(i!=3)
{
s[i]=a/base+'0';
a = a%base;
base=base/10;
}
}
printf("%s %d\n",s, count);
}
int main()
{
int n,i,j,flag=0,phone;
char s[256];
int *list = (int*)malloc(10000000*sizeof(int));
for(i=0; i<10000000; i++) list[i]=0;
scanf("%d", &n);
for(i=0; i<n; i++)
{
scanf("%s", s);
phone = transform(s);
list[phone]++;
}
for(i=0; i<10000000; i++)
{
if(list[i]>1)
{
flag=1;
print(i, list[i]);
}
}
if(!flag) printf("No duplicates.");
return 0;
}