【问题描述】
Vasya有几本电话簿,记录了他的朋友们的电话号码,每一个朋友都可以有一或几个电话号码。
Vasya决定整理关于朋友电话号码的信息。给定n个字符串,来自于Vasya的电话簿中的条目。每一条都以朋友的姓名开头,然后跟着当前条目中的电话号码个数,然后是本人的电话号码。有可能几个相同的电话被记录在同一个记录中。
Vasya还认为,如果电话号码a是电话号码b的后缀(也就是说,号码b以a结尾),这两个号码被当作同一个电话号码,那么a被认为是无城市代码,它不应该被考虑。
输出整理后Vasya朋友的电话号码信息。有可能两个不同的人有相同的号码。如果一个人有两个电话号码x和y,x是y的后缀(即y以x结尾),则不输出x。
如果Vasya的电话簿中的某些朋友记录了几次,那么只需要记录一次。
【输入形式】
输入第一行一个整数n(1<=n<=20),Vasya的电话簿上的条目数。
以下n行后面是描述中的格式记录。 朋友的姓名中不包含空字符,长度不超过10位,由小写英文字母组成。电话号码个数在110之间。每个电话号码的长度范围在110之间,可以包含前导0。
【输出形式】
输出Vasya的朋友的电话号码的有序信息。首先输出电话簿中的朋友数目m。
接下来的m行,包含以格式“姓名 电话号码个数 电话号码1 … 电话号码k"的条目,号码间以空格分隔。每个记录包含当前朋友的所有电话号码。
每个条目输出按照姓名字母序进行排序,电话号码按照从小到大的顺序排列(注意电话号码比较规则:“1”<“01”、“12”<“012”,依此类推)
【样例输入】
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<set>
using namespace std;
map<string,vector<string> >peopleInfo;
int* getNext(string pattern)
{
int * next = new int[pattern.size()];
int n = pattern.size();
int j = -1;
next[0] = -1;
for(int i = 1 ; i < n ; i ++)
{
while(j != -1 && pattern[j + 1] != pattern[i])
{
j = next[j];
}
if(pattern[j + 1] == pattern[i])
{
j++ ;
}
next[i] = j;
}
return next;
}
bool KMP(string text , string pattern){
//get next
int n = text.size(), m = pattern.size();
if(n < m)return false;
int * next = getNext(pattern);
int j = -1;
for(int i = 0 ; i < n ; i ++)
{
while( j != -1 && text[i] != pattern[j + 1]){
j = next[j];
}
if(text[i] == pattern[j + 1])j++;
if(j == m - 1 && (i == n - 1 ) )return true;
}
//free space
delete next;
return false;
}
bool compare(string a, string b)
{
if(a.size() != b.size() )
{
return a.size() < b.size();
}
return a < b;
}
int main()
{
int n = 0;
cin>>n;getchar();
string name; string number;
while(n--)
{
cin>>name;getchar();
getline(cin,number);
string tmp;
for(int i = 2 ; i < number.size() ; i ++)
{
if(number[i] != ' ')tmp+=number[i];
else {
peopleInfo[name].push_back(tmp);
tmp = "";
}
}
peopleInfo[name].push_back(tmp);
tmp = "";
}
// cout<<"*****************"<<endl;
// for(auto&v:peopleInfo)
// {
// cout<<v.first<<" ";
// for(auto&m:v.second )
// {
// cout<<m<<" ";
// }
// cout<<endl;
// }
// cout<<"****************"<<endl;
for(auto& v : peopleInfo)
{
sort(v.second.begin(), v.second.end(),compare);
// cout<<"*************"<<endl;
// for(auto&m:v.second )
// {
// cout<<m<<" ";
// }
// cout<<endl<<"*************"<<endl;
vector<string> newInfo;
string name = v.first;
for(int i = 0 ; i < v.second.size() ; i ++)
{
bool flag = true;
for(int j = i + 1 ; j < v.second.size() ; j ++)
{
if( KMP(v.second[j],v.second[i]) == true){
flag = false;
}
}
if(flag)
newInfo.push_back(v.second[i]);
}
// newInfo.push_back(v.second[v.second.size() - 1] );
peopleInfo[name] = newInfo;
}
cout<<peopleInfo.size()<<endl;
for(auto&v:peopleInfo)
{
cout<<v.first<<" "<<v.second.size()<<" ";
for(auto&m:v.second )
{
cout<<m<<" ";
}
cout<<endl;
}
}