题目
给定一系列的单词,请把由相同字母组成的单词分为一组,并将所有的分组输出。(要求:按照单词在输入序列中出现的顺序输出分组)
【输入】一系列的单词(单词数量少于1000)
【输出】
分组数x
第一个分组的单词
第二个分组的单词
第x个分组的单词
例如:
【输入】
eat tea tan ate nat bat eate
【输出】
3
eat tea ate eate
tan nat
bat
思路
- 相同字母构成的单词需要被分在一组里,考虑用不同的素数表示每一个字母,因为不同素数的乘积一定不同(力扣上看到的思想),每个单词都算出其对应素数相应的乘积,乘积相同则为一组
- 排序时先看是否由相同字母构成,再根据输入的顺序输出,考虑用结构体数组,记录输入的字符串和相应的素数乘积
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
// from 0vv
int letter_num[26]={2,3,5,7,11,
13,17,19,23,29,
31,37,41,43,47,
53,59,61,67,71,
73,79,83,89,97,101 }; //每个字母对应的素数
struct team
{
char word[1111]; //输入的单词
long long sum; //记录乘积
int isp; //记录是否已经输出过
};
long long mul(char *s)
{
int letter[26]={0}; //记录某个字母是否出现过,出现过则不计入乘积
long long res=1;
while(*s)
{
if(letter[*s-'a']==0) //该字母没有出现过
{
res*=letter_num[*s-'a'];
letter[*s-'a']=1;
}
s++;
}
return res;
}
int main()
{
team myteam[1111];
int i=0;
while(scanf("%s",myteam[i].word)!=EOF)
{
//cout<<myteam[i].word<<endl;
myteam[i].isp=1;
i++;
}
int cnt=0; //记录分组数
for(int j=0;j<i;j++)
{
int sign=1;
myteam[j].sum=mul(myteam[j].word);
//cout<<myteam[j].sum<<endl;
for(int k=0;k<j;k++)
{
if(myteam[j].sum==myteam[k].sum)
sign=0;
}
if(sign)
cnt++;
}
cout<<cnt<<endl;
for(int j=0;j<i;j++)
{
int s=0;
if(myteam[j].isp)
{
cout<<myteam[j].word<<" ";
}
for(int k=j+1;k<i;k++)
{
if(myteam[k].sum==myteam[j].sum&&myteam[k].isp)
{
cout<<myteam[k].word<<" ";
myteam[k].isp=0;
s=1;
}
}
//处理换行
if(s)
cout<<endl;
else if(myteam[j].isp)
cout<<endl;
}
return 0;
}