解体思想:
1.获取输入直接将输入转化成数字字符组成的电话号码。
2.将数字字符转化的字符整数化(这块我是手工转换的,有函数可以直接执行)
3.利用哈希映射方式保存电话号码出现的次数。(数组下标代表电话号,元素值代表电话号出现的次数)
4.从映射数组开始遍历输出重复次数不为1的电话号,若没有输出,则输出No duplicates.
1.输入要求
1)第一行指定电话号码中的电话号码(最多100,000)
2)其余的行列出目录中的电话号码,每个号码单独在一行上。
3)每个电话号码由一个由十进制数字,大写字母(不包括Q和Z)和连字符组成的字符串组成。字符串中只有七个字符是数字或字母。
对于输入电话号码的要求其实很明确,就是7个数字或字母,所以完全可以在获取输入的时候直接剔除无效字符:
while( i < LENPHO )
{
scanf( "%c", &phone[i] ) ;
// fscanf( fp, "%c", &phone[i] ) ;
if ( ( ( phone[i] >= '0' ) && ( phone[ i ] <= '9' ) ) || (( phone[i] >= 'A' ) && ( phone[ i ] <= 'Z' )) )
{
phone[ i ] = ( phone[ i ] >= 'A' ) ? ( table[ phone[ i ] - 'A' ] + '0' ) : phone[ i ] ;
i++ ;
}
}
phone[ LENPHO ] = '\0' ;
【说明】table表是字母与字符代表数字的映射。字母的下标从0到25依次对应A-Z。元素值代表字母代表的电话号码。
2.字符转化成整型,并记录电话号码出现的次数
k = 1000000 ;
phe = 0 ;
for (int i = 0; i < LENPHO; ++i)
{
phe += k * ( phone[ i ] - '0' ) ;
k /= 10 ;
}
// printf( "phe = %d\n", phe ) ;
number[ phe ] += 1 ;
3.按要求输出
for (int i = 0; i <= N; ++i)
{
if (number[ i ] > 1 )
{
flag = 1 ;
printf("%03d-%04d %d\n", i/10000, i% 10000, number[i] );
}
}
if ( flag == 0 )
{
printf("No duplicates.\n");
}
4.完整代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 9999999
#define LENPHO 7
int table[] = { 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 0, 7, 7, 8, 8, 8, 9, 9, 9, 0 } ;
int number[ N ] ;
int main()
{
int n ;
char phone[ LENPHO + 1 ] ;
int i ;
int k ;
int phe ;
int flag = 0 ;
scanf( "%d", &n ) ;
// FILE* fp = fopen("in.txt", "r") ;
// fscanf( fp, "%d", &n ) ;
memset( number, 0, sizeof(int) * N ) ;
while( n-- > 0)
{
i = 0 ;
while( i < LENPHO )
{
scanf( "%c", &phone[i] ) ;
// fscanf( fp, "%c", &phone[i] ) ;
if ( ( ( phone[i] >= '0' ) && ( phone[ i ] <= '9' ) ) || (( phone[i] >= 'A' ) && ( phone[ i ] <= 'Z' )) )
{
phone[ i ] = ( phone[ i ] >= 'A' ) ? ( table[ phone[ i ] - 'A' ] + '0' ) : phone[ i ] ;
i++ ;
}
}
phone[ LENPHO ] = '\0' ;
// printf( "phone = %s\n", phone ) ;
//transmit char* to int
k = 1000000 ;
phe = 0 ;
for (int i = 0; i < LENPHO; ++i)
{
phe += k * ( phone[ i ] - '0' ) ;
k /= 10 ;
}
// printf( "phe = %d\n", phe ) ;
number[ phe ] += 1 ;
}
for (int i = 0; i <= N; ++i)
{
if (number[ i ] > 1 )
{
flag = 1 ;
printf("%03d-%04d %d\n", i/10000, i% 10000, number[i] );
}
}
// printf("%d\n", count);
if ( flag == 0 )
{
printf("No duplicates.\n");
}
return 0 ;
}
5.注意事项
1)电话号码是7为数,如果将整型数组在函数中声明,那么整型数组将会占用函数栈的内存,函数栈的内存是不足以这么多整型变量开辟的,所以要将整型数组声明在函数之外,这将会使的数组占用的是堆。堆的大小是相当大的。
2)输出,输出的时候很容易忘记0000001这种情况,所以在输入的时候完全就可以利用格式控制字符串去进行控制。
如果文章中说的哪里有问题,还希望指正。谢谢