【C++】重复的电话号码

/*
功能: 检查是否有两个或多个公司拥有相同的电话号码,并统计输出
接口函数: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");
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值