2.4 电话号码

ps:要是有更好,更新颖的方法,欢迎分享
【法一:单纯用map】

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;
struct FFri{
	int num;
	string phone[100];
};
struct Fri{
	string name;
	int num;
	string phone[100];
};
bool cmp1(const Fri& left,const Fri& right)
{
	if(left.name!=right.name)
	return left.name<right.name;
	return true;
}
bool cmp2(const string& left,const string& right)
{
	if(left.length()!=right.length())
	return left.length()<right.length();
	return left<right;
}
int main()
{
	int n;
	cin>>n;
	map<string,FFri> per;
	while(n--)
	{
		string name;
		cin>>name;
		int num;
		cin>>num;
		for(int i=0;i<num;i++)
		{
			string p;
			int flag =0;
			cin>>p;
			for(int j=0;j<per[name].num;j++)
			{
				if(p==per[name].phone[j])//判断现要存的号码是否已存 
				{
					flag=1;
					break;
				}
				else//未存,判断是否为已存的后缀 
				{
					string str= per[name].phone[j]; 
					if(p.length()<str.length()&&str.substr(str.length()-p.length())==p)// 为已存后缀,不需要再存 
					{
						flag=1;
						break;
					}
					else if(str.length()<p.length()&&p.substr(p.length()-str.length())==str)//已存的号码为现存的后缀,把已存的号码更新为现存的 
					{
						per[name].phone[j]=p;
						flag=1;
						break;
					}
				}	
			}
			if(flag==0) 
			{
				per[name].phone[per[name].num]=p;
				per[name].num++;
			}
		}
	}
	vector<Fri> f;
	for(map<string,FFri>::iterator it=per.begin();it!=per.end();it++)
	{
		Fri tmp;
		tmp.name=it->first;
		tmp.num=it->second.num;
		for(int i=0;i<tmp.num;i++)
		{
			tmp.phone[i]=it->second.phone[i];
		}
		f.push_back(tmp);
	}
	sort(f.begin(),f.end(),cmp1);//按照朋友名字排序 
	for(int i=0;i<(int)f.size();i++)
	{
		sort(f[i].phone,f[i].phone+f[i].num,cmp2);//每个朋友的电话号码排序 
	}
	cout<<f.size()<<endl;
	for(int i=0;i<(int)f.size();i++)
	{
		cout<<f[i].name<<" "<<f[i].num<<" ";
		for(int j=0;j<f[i].num;j++)
		cout<<f[i].phone[j]<<" ";
		cout<<endl;
	}
}

ps:(1)下面是错了最后五个数据的后缀函数,最开始犯的错误我没有想到用sustr(),而是选择用find来查找后缀,错误的原因就是:如果长的号码不仅中间包含短的号码,后面还包含短的号码,查找到的是中间的那个,会被误判不为同一个号码。
举个栗子:01212 12
len1=5, len2=2, 01212=find(12)=1, 1+2!=5,就被判为12不是01212的后缀
(2)还有一个越界的错误,就是电话号码的数组开少了,一旦号码超过10个,就不行了
【法二:用map和set去重】

#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
bool cmp(const string& left,const string& right)
{
	if(left.length()!=right.length())
	return left.length()<right.length();
	return left<right;
}
int main(){
	int n;
	cin>>n;
	map<string,set<string>> per;
	while(n--)
	{
		string name;
		cin>>name;
		int num;
		cin>>num;
		while(num--) 
		{
			string p;//电话号码
			cin>>p;
			per[name].insert(p); //先将相同的电话号码去掉 
		}
	}
	cout<<per.size()<<endl;
	for(map<string,set<string>>::iterator itm=per.begin();itm!=per.end();itm++)//遍历每个不同的人 
	{
		vector<string> phone;
		phone.clear();
		for(set<string>::iterator it1=itm->second.begin();it1!=itm->second.end();it1++)//遍历这个人的所有号码 
		{
			string tmp1=*it1;
			int flag=0;
			for(set<string>::iterator it2=itm->second.begin();it2!=itm->second.end();it2++)//查找这个人号码里时候含有是后缀的号码 
			{
				string tmp2=*it2;
				if(tmp1==tmp2)
				continue;
				if(tmp1.length()<tmp2.length()
				&&tmp2.substr(tmp2.length()-tmp1.length())==tmp1)//判断tmp1是否是tmp2的后缀 
				{
					flag=1;
					break;
				}
			}
			if(flag==0)
			phone.push_back(tmp1);
		}
		sort(phone.begin(),phone.end(),cmp);
		cout<<itm->first<<" "<<phone.size()<<" ";
		for(int i=0;i<(int)phone.size();i++)
		cout<<phone[i]<<" ";
		cout<<endl;
	}
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值