注: 由于UVa服务器原因. 这题提交时总是提示"Submission error", 在网上找了别人的答案提交也总是这个结果, 只能过一段进间再看看能不能 AC 了.
题意:
读入按不同格式存储的电话号码, 把它们都转成标准电话号码 xxx-yyyy 的格式, 然后把出现次数大于1的电话号码及其出现次数都输出来. 若没有出现次数大于1的电话号码, 就输出: No duplicates.
思路:
每读入一个电话码码, 就按以下操作把它转成标准格式, 再存到 map<电话号码, 出现次数> 里, 最后再把出现次数大于 1 的输出即可.
1. 去掉所有 -
2. 第四位放 -
3. 把字母转成相应的数字
要点:
1. int 加上 '0' 可以转成 char.
2. map 加了 const 之后,就不能再用 [] 取值了,因为这个操作可能会往 map 里面添加数据.
代码:
# include <iostream>
# include <string>
# include <cstdio>
# include <cstring>
# include <vector>
# include <algorithm>
# include <cctype>
# include <iterator>
# include <assert.h>
# include <map>
using namespace std;
// 服务器问题,未AC
// map find
// int -> char
// map 加了 const 之后,就不能再用 [] 取值了,因为这个操作可能会往 map 里面添加数据
// map 的 begin 与 end 是默认排好序的, 可以通过设置 key_comp 来改变排序
// 初始化 字母 到 数字 的映射
void initMapping(map<char, int>& letr2num) {
letr2num['A'] = 2;
letr2num['B'] = 2;
letr2num['C'] = 2;
letr2num['D'] = 3;
letr2num['E'] = 3;
letr2num['F'] = 3;
letr2num['G'] = 4;
letr2num['H'] = 4;
letr2num['I'] = 4;
letr2num['J'] = 5;
letr2num['K'] = 5;
letr2num['L'] = 5;
letr2num['M'] = 6;
letr2num['N'] = 6;
letr2num['O'] = 6;
letr2num['P'] = 7;
letr2num['R'] = 7;
letr2num['S'] = 7;
letr2num['T'] = 8;
letr2num['U'] = 8;
letr2num['V'] = 8;
letr2num['W'] = 9;
letr2num['X'] = 9;
letr2num['Y'] = 9;
}
// 把读入的电话转成标准表示l
// 1. 去掉 -
// 2. 把 字母 转成 数字
// 3. 按 xxx-yyyy 的格式返回
string standerFormat(const string& line, const map<char, int>& letr2num) {
char phone[8];
int idx = 0;
// 1. 去掉 -
for (int i=0; i<line.size(); i++) {
if (line[i] != '-')
phone[idx++] = line[i];
// 第四位要放 -
if (idx == 3)
phone[idx++] = '-';
}
// 2. 把字母转成数字
for (int i=0; i<8; i++) {
if (i==3)
continue;
map<char, int>::const_iterator it = letr2num.find(phone[i]);
if (it != letr2num.end()) {
phone[i] = (*it).second + '0'; // int 转 char
}
}
return phone;
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("755_i.txt", "r", stdin);
freopen("755_o.txt", "w", stdout);
#endif
map<char, int> letr2num;
initMapping(letr2num);
int numDatabase;
cin >> numDatabase;
while (numDatabase--) {
int numPhone;
cin >> numPhone;
cin.ignore(); // cin 后接 getline 一定要有 ignore
map<string, int> phoneCount; // 记录每个 phone 及其出现的次数
string line;
while (numPhone--) {
getline(cin, line);
string phone = standerFormat(line, letr2num);
phoneCount[phone] = phoneCount[phone] + 1;
}
// 只取出现次数大于 1 的
vector<string> phones;
for (map<string, int>::const_iterator it = phoneCount.begin();
it != phoneCount.end(); it++) {
if ((*it).second > 1) {
phones.push_back((*it).first);
}
}
// 排序
sort(phones.begin(), phones.end());
// 把出现次数大于1的输出
for (vector<string>::iterator it = phones.begin();
it != phones.end(); it++) {
cout << *it << " " << phoneCount[*it] << endl;
}
if (phones.empty()) {
cout << "No duplicates." << endl;
}
if (numDatabase > 0)
cout << endl;
}
return 0;
}
环境: C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE