题目描述
给你一个N表示下边有N个字符串,每个字符串第一个表示这个朋友的名字,后边是这几个电话号码,每两个电话号码之间以空格隔开。然后是让你帮他整理手机号,如果a是b的后缀,那么就会删除a,让我们输出整理后的电话号。
Input
4
ivan 3 123 123 456
ivan 2 456 456
ivan 8 789 3 23 6 56 9 89 2
dasha 2 23 789
Output
2
dasha 2 23 789
ivan 4 789 123 2 456
map<string,set<string>>
用
map<string,set<string>
>存储就可以满足每个名字,可以对应很多不重复的电话号。但是还有去后缀没有实现,直接去删除有些麻烦。所以我们在可以输出的时候想办法。输出的时候对于一个人的这些电话号,我们可以把不是其他电话号的后缀的电话号先存到一个数组里面,处理完以后输出。
C++ 代码
#include<iostream>
#include<stdio.h>
#include<queue>
#include<iomanip>
#include<algorithm>
#include<stack>
#include<string.h>
#include<map>
#include<math.h>
#include<set>
#define maxn 1000005
#define inf 0x3f3f3f3f
#define ll long long
#define endl '\n'
using namespace std;
map<string,set<string>>mp;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
//1.用map<string,set<string>>将各个名字对应的num存下来
//2. 用迭代器遍历set,将重复后缀的删除掉
//3.输出当前set的size,和所有set对应的num
int t;
cin>>t;
while(t--){
string name;
cin>>name;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
string num;
cin>>num;
mp[name].insert(num);
}
}
cout<<mp.size()<<endl;
for(auto i:mp) //这个i迭代的是整个map,包括name(string),和num(setstring)
{
auto x=i.second; //用 x来 迭代所有的num
for(auto j:x) //用 j来 迭代当前x每个num 去判断删除
{
for(int y=1;y<j.size();y++)
{ //用count计数函数来判断此num的后缀是否出现过,若有返回非负数,用erase删除set中的那个num,而且由于set存储默认去重,也就是删除了所有的
if(x.count(string(j.begin()+y,j.end())))
{
x.erase(string(j.begin()+y,j.end()));
}
}
}
cout<<i.first<<' '<<x.size()<<' ';
for(auto o:x) //用 o来 迭代当前x每个num 去输出删除后的num
cout<<o<<' ';
cout<<endl;
}
return 0;
}