/*
功能: 检查是否有两个或多个公司拥有相同的电话号码,并统计输出
接口函数:int PhoneBookProcess(const char *inFileName, const char *outFileName)
输入参数: inFileName - 包含个性电话号码个数与列表的源文件名
outFileName - 输出统计重复号码的结果的目标文件名
返回值: 0 - 成功
1 - 其它各种错误,如文件不存在
*/
/*法一:用map*/
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <fstream>
using namespace std;
int deleteLine(string str) //将输入字符串去掉‘-’、完成字母到数字的对应转换,最终输出为整数
{
int i = 0, j = 0,num=0,n=0;
int len = str.length(); //每一个字符串的长度
string temp;
for (i = 0; i < len; i++){
if (str[i] >= '0'&&str[i] <= '9' || str[i] >= 'A'&&str[i] <= 'Z' || str[i] >= 'a'&&str[i] <= 'z')
{
switch (str[i])
{
case '0':n = 0; break;
case '1':n = 1; break;
case '2':
case 'A':case 'a':
case 'B':case 'b':
case 'C':case 'c':n = 2; break;
case '3':
case 'D':case 'd':
case 'E':case 'e':
case 'F':case 'f':n = 3; break;
case '4':
case 'G':case 'g':
case 'H':case 'h':
case 'I':case 'i':n = 4; break;
case '5':
case 'J':case 'j':
case 'K':case 'k':
case 'L':case 'l':n = 5; break;
case '6':
case 'M':case 'm':
case 'N':case 'n':
case 'O':case 'o':n = 6; break;
case '7':
case 'P':case 'p':
case 'Q':case 'q':
case 'R':case 'r':
case 'S':case 's':n = 7; break;
case '8':
case 'T':case 't':
case 'U':case 'u':
case 'V':case 'v':n = 8; break;
case '9':
case 'W':case 'w':
case 'X':case 'x':
case 'Y':case 'y':
case 'Z':case 'z':n = 9; break;
default:break;
}
num = num * 10 + n;
}
}
return num;
}
int PhoneBookProcess(const char *inFileName, const char *outFileName){
if (!inFileName)
return 1;
ifstream fs(inFileName);//创建文件读取对象
string s1;
int i, a;
map<int, int> m;
map<int,int>::iterator k;
int num = 0;
int flag = 0;
fs >> s1; //读取第一行内容(电话号码个数)放入S1中
a = deleteLine(s1);
for (i = 0; i < a; i++)
{
fs >> s1; //依次读取每一行内容
int num = deleteLine(s1);
if (num){
m[num]++; //号码放入map m中,num为号码,m[num]为该号码出现的次数,分别对应map中的内容值和键值,出现该号码时,该号码对应的键值加1
//cout << m[num] << ',' << num << endl;
}
}
ofstream out(outFileName);//创建文件写入对象
if (!out){
return 1;
}
for (k = m.begin(); k != m.end(); k++) //遍历m,若存在键值>1的元素,则说明有重复号码
{
if (k->second > 1)
flag = 1;
}
if (flag == 0) //无重复号码
out << "No duplicates." << endl;
else
{
for (k = m.begin(); k != m.end(); k++)
{
if (k->second > 1){
out << k->first << ' ' << k->second << endl; //将重复号码及重复次数输出到文件outFileName中
cout << k->first << ' ' << k->second << endl;
}
}
}
fs.close();
out.close();
return 0;
}
void main()
{
PhoneBookProcess("ME.dat", "ME.out");
system("pause");
}
/*法二:用set和vector,运行时间长,效率不如map高,在限制运行时间的条件下可采用法一*/
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <fstream>
using namespace std;
string deleteLine(string str) //将输入字符串去掉‘-’及前缀0、完成字母到数字的对应转换,输出纯数字的字符串
{
int i = 0, j = 0;
int len = str.length();
string temp;
for (i = 0; i < len ; i++){ //逐个字符判断
switch (str[i])
{
case '0': temp.push_back(str[i]); break;
case '1':temp.push_back(str[i]); break;
case '2':
case 'A':
case 'B':
case 'C':temp.push_back('2'); break;
case '3':
case 'D':
case 'E':
case 'F':temp.push_back('3'); break;
case '4':
case 'G':
case 'H':
case 'I':temp.push_back('4'); break;
case '5':
case 'J':
case 'K':
case 'L':temp.push_back('5'); break;
case '6':
case 'M':
case 'N':
case 'O':temp.push_back('6'); break;
case '7':
case 'P':
case 'Q':
case 'S':
case 'R':temp.push_back('7'); break;
case '8':
case 'T':
case 'U':
case 'V':temp.push_back('8'); break;
case '9':
case 'W':
case 'X':
case 'Y':
case 'Z':temp.push_back('9'); break;
default:break;
}
}
temp.push_back('\0');
return temp;
}
int PhoneBookProcess(const char *inFileName, const char *outFileName){
if (!inFileName)
return 1;
ifstream fs(inFileName); //创建文件读取对象
string s1;
vector<int> s2;
set<int> s3;
string s4;
set<int>::iterator k;
int num = 1;
fs >> s1; //读第一行字符串(号码个数)
while (fs >> s1) //依次读取后面的每一行字符串(号码)
{
s4 = deleteLine(s1);
int n = atoi(s4.c_str()); //字符串转换为数字
if (n){
s2.push_back(n); //号码入vector,vector中保留所有号码
s3.insert(n); //号码入set,以去除重复号码,使输入号码在set中只出现一次
}
}
ofstream out(outFileName); //创建文件写入对象
if (!out){
return 1;
}
if (s2.size() != s3.size()) //若vector长度!=set长度,说明有重复号码
{
for (k = s3.begin(); k != s3.end(); k++)
{
num = count(s2.begin(), s2.end(), *k); //统计set中每一个号码在vector中出现的次数num
if (num > 1) //该号码有重复,则输出到outFileName中
out << *k << ' ' << num << endl;
}
}
else
out<<"No duplicates."<< endl;
out.close();
return 0;
}
void main()
{
PhoneBookProcess("ME.dat", "ME.out");
system("pause");
}