题目描述
Oliver 为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类。
两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等。
例如 AABACAABAC,它和 CBAAACBAAA 就可以归为一类,而和 AAABBAAABB 就不是一类。
现在Oliver有 �N 个单词,所有单词均由大写字母组成,每个单词的长度不超过 100100。你要告诉 Oliver 这些单词会被分成几类。
输入格式
输入文件的第一行为单词个数 �N,以下 �N 行每行为一个单词。
输出格式
输出文件仅包含一个数,表示这 �N 个单词分成的类数。
输入输出样例
输入 #1复制
3 AABAC CBAAA AAABB
输出 #1复制
2
说明/提示
- 对于 70%的数据满足 1≤N≤100;
- 对于 100%的数据满足 1≤N≤10000。
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e6 + 10;
int e[N][27]; //用于存储每个字符串对应字符出现的次数
char str[N];
int n, k, sum;
int main()
{
bool flag;
cin >> n;
int m = n;
while (n--)
{
cin >> str;
int len = strlen(str);
for (int i = 0; i < len; i++)
{
int c = str[i] - 'A';
e[k][c]++; //每出现一次,对应位置就++
}
k++;
}
int v = m;
for (int i = 0; i < m; i++)
{
if (e[i][26] == -1)continue; //如果最后的位置等于-1,就代表标记过了,就不需要再接着判断
for (int j = i + 1; j < m; j++)
{
flag = true;
for (int p = 0; p < 26; p++)
{
if (e[i][p] != e[j][p])
{
flag = false; //用于判断两个字符串是否相等
break;
}
}
if (flag)
{
//如果相等,就在最后的位置标记一下,避免重复判断
e[j][26] = -1;
v--; //相等一次种类当然就减少一个
}
}
}
cout << v << endl;
return 0;
}
算法小白的刷题日记--字符串单词分类