【查表+找重复】电话号码的字母映射

问题链接ZOJ1159 UVA755 UVALive5420 487-3279

问题简述:为了好记电话号码,将字母映射为数字,人们就可以记忆字母了。给定若干的电话号码,如果没有重复就不输出,如果有重复则输出电话号码及重复次数。如果没有一个电话号码是重复的,则输出“No duplicates”。

问题分析:这个问题的关键是用什么样的数据结构存储有关的信息。需要找到最简洁的字母转换数字的方式,电话号码的存储方式。

程序说明:这个问题与参考链接的问题是同一问题,只是输入输出形式不同。

题记:(略)

Sample Input 

1

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279


Sample Output

310-1010 2
487-3279 4
888-4567 3


大致思路:

输入形式以字符串来存储,每输入一个字符串,就对其中每个字符进行isdigit和isupper的判断(这样直接就不对'-'处理,忽略'-'),其中,upper的处理用了“查表”方法。然后用一个num巧妙地把该字符串转换成一个整数,并存储入最终需要的整数数组ans中。

然后要对ans进行sort排序(这样的话就可以方便“找重复”的计数),然后依次前后进行对比即可,重复则count++。直到有不同的且count>1则输出之前的重复序列,并重新将count置为1。这样的话就要考虑在遍历完成后再去输入count>1的序列。如果遍历结束后count=1,且flag==0(没有进入过重复的if语句),则no duplicates.

  1. /* ZOJ1159 UVA755 UVALive5420 487-3279 */  
  2.   
  3. #include <iostream>  
  4. #include <algorithm>  
  5. #include <stdio.h>  
  6. #include <ctype.h>  
  7.   
  8. using namespace std;  
  9.   
  10. int convert[] =  
  11. {  
  12.     2, 2, 2,  
  13.     3, 3, 3,  
  14.     4, 4, 4,  
  15.     5, 5, 5,  
  16.     6, 6, 6,  
  17.     7, 0, 7, 7,  
  18.     8, 8, 8,  
  19.     9, 9, 9,  
  20.     0  
  21. };  
  22.   
  23. const int N = 128;  
  24. char s[N];  
  25. const int N2 = 100000;  
  26. int ans[N2], acount;  
  27.   
  28. int main()  
  29. {  
  30.     int t, n, num;  
  31.     bool tflag = false;  
  32.   
  33.     scanf("%d", &t);  
  34.     while(t--) {  
  35.         if(tflag)  
  36.             printf("\n");  
  37.         tflag = true;  
  38.   
  39.         scanf("%d", &n);  
  40.         for(int k=0; k<n; k++) {  
  41.             scanf("%s", s);  
  42.   
  43.             num = 0;  
  44.             for(int i=0; s[i]; i++) {  
  45.                 if(isdigit(s[i])) {  
  46.                     num *= 10;  
  47.                     num += s[i] - '0';  
  48.                 } else if(isupper(s[i])) {  
  49.                     num *= 10;  
  50.                     num += convert[s[i] - 'A'];  
  51.                 }  
  52.             }  
  53.             ans[k] = num;  
  54.         }  
  55.   
  56.         sort(ans, ans + n);  
  57.   
  58.         bool flag = true;  
  59.         int count = 1;  
  60.         for(int i=1; i<n; i++) {  
  61.             if(ans[i] == ans[i - 1])  
  62.                 count++;  
  63.             else {  
  64.                 if(count > 1) {  
  65.                     printf("%03d-%04d %d\n", ans[i - 1] / 10000, ans[i - 1] % 10000, count);  
  66.                     flag = false;  
  67.                 }  
  68.                 count = 1;  
  69.             }  
  70.         }  
  71.         if(count > 1) {  
  72.             printf("%03d-%04d %d\n", ans[n - 1] / 10000, ans[n - 1] % 10000, count);  
  73.             flag = false;  
  74.         }  
  75.   
  76.         if(flag)  
  77.             printf("No duplicates.\n");  
  78.     }  
  79.   
  80.     return 0;  
  81. }  

学到的点:

查表法——尤其是字母与数字间的转换

②isdigit和isupper函数的运用

③num*10的运用——将一个字符串转成一个数字

数组排序——找重复时先排好序,这样就可以直接依次前后比较了。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值