11、487-3279

Description

Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or phrase. For example, you can call the University of Waterloo by dialing the memorable TUT-GLOP. Sometimes only part of the number is used to spell a word. When you get back to your hotel tonight you can order a pizza from Gino's by dialing 310-GINO. Another way to make a telephone number memorable is to group the digits in a memorable way. You could order your pizza from Pizza Hut by calling their ``three tens'' number 3-10-10-10.

The standard form of a telephone number is seven decimal digits with a hyphen between the third and fourth digits (e.g. 888-1200). The keypad of a phone supplies the mapping of letters to numbers, as follows:

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

There is no mapping for Q or Z. Hyphens are not dialed, and can be added and removed as necessary. The standard form of TUT-GLOP is 888-4567, the standard form of 310-GINO is 310-4466, and the standard form of 3-10-10-10 is 310-1010.

Two telephone numbers are equivalent if they have the same standard form. (They dial the same number.)

Your company is compiling a directory of telephone numbers from local businesses. As part of the quality control process you want to check that no two (or more) businesses in the directory have the same telephone number.

Input

The input will consist of one case. The first line of the input specifies the number of telephone numbers in the directory (up to 100,000) as a positive integer alone on the line. The remaining lines list the telephone numbers in the directory, with each number alone on a line. Each telephone number consists of a string composed of decimal digits, uppercase letters (excluding Q and Z) and hyphens. Exactly seven of the characters in the string will be digits or letters.

Output

Generate a line of output for each telephone number that appears more than once in any form. The line should give the telephone number in standard form, followed by a space, followed by the number of times the telephone number appears in the directory. Arrange the output lines by telephone number in ascending lexicographical order. If there are no duplicates in the input print the line:

No duplicates.

Sample Input

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
 
 
解题思路:这道题是一道格式转换,排序,计算重复元素的综合题。格式转换的部分较为简单,就是将A-Z转换为对应的的1-9,最后以310-1010这样的格式出现。对于排序和计数,一开始我是分开进行的,但是这样就又尴尬地造成了超时的问题,所以参考了一些博客,用键值对的方法map可以将二者合一,因为map默认按顺序放置键值对,所以只需要进行计数即可。以最后的格式字符串作为键,以该字符串出现的次数为值,将键值对存放于map中。其中遍历时用到 iterator迭代器,第一次为字符串格式转换时,遍历字符串的每一个字符;第二次为输出键值对时,遍历map中每一个键值对。
具体代码:
 1 #include<map>
 2 #include<iostream>
 3 #include<string>
 4 using namespace std;
 5 
 6 char traslate[26] = { '2', '2', '2', '3', '3', '3', '4', '4', '4',
 7                       '5', '5', '5', '6', '6', '6', '7', '7', '7',
 8                       '7', '8', '8', '8', '9', '9', '9', '9' };
 9 
10 string numFormat(string inputNum){
11      string outputNum;
12      for (string::iterator it = inputNum.begin(); it != inputNum.end(); ++it){
13            if (*it >= '0' && *it <= '9')
14 
15                 outputNum.push_back(*it);
16            if (*it >= 'A' && *it <= 'Z')
17 
18                 outputNum.push_back(traslate[*it-'A']);
19      }
20      outputNum.insert(3, 1, '-');
21      return outputNum;
22 }
23 
24 int main(){
25      int num;
26      int flag = 0;
27      cin >> num;
28      string *numbers=new string[num];
29      for (int i = 0; i < num; i++){
30            cin >> numbers[i];
31            numbers[i] = numFormat(numbers[i]);
32      }
33      map<string, int> m;
34      for (int i = 0; i < num; i++){
35            if (m.find(numbers[i]) != m.end()){
36                 ++m[numbers[i]];
37                 flag = 1;
38            }
39            else
40                 m.insert(pair<string, int>(numbers[i], 1));
41      }
42      if (flag == 1){
43            map<string, int>::iterator it;
44            for (it = m.begin(); it != m.end(); ++it){
45                 if (it->second >= 2)
46                      cout << it->first <<" "<< it->second << endl;
47            }
48      }
49      else
50            cout << "No duplicates." << endl;
51      return 0;
52 }

做题感悟:我最大的收获就是学到了一些map的使用方法,它还有很多其他功能,我暂时用不到。而且在使用map或字符串时可以结合  iterator 使用。

原文地址:https://www.cnblogs.com/langzi1996/p/6526655.html