POJ1002

解体思想:

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这种情况,所以在输入的时候完全就可以利用格式控制字符串去进行控制。

如果文章中说的哪里有问题,还希望指正。谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值