题目描述
只由小写字母(a~z)组成的一批字符串,都放在字符类型的数组String[] arr中,
如果其中某两个字符串,所含有的字符种类完全一样,就将两个字符串算作一类 比如:baacba和bac就算作一类
虽然长度不一样,但是所含字符的种类完全一样(a、b、c) 返回arr中有多少类?
题目解析
位运算
思路
一共有29种字符,一个整数有32位。
用这个整数的第0位表示a是否出现过,1是否出现过…
最后看这个set中还留下了多少个不同的整数
实现
class Solution {
public:
int types(std::vector<std::string> &arr) {
std::set<int> types;
for(auto str : arr){
int N = str.size();
int key = 0;
for (int i = 0; i < N ; ++i) {
key |= (1 << (str[i] - 'a'));
}
types.emplace(key);
}
return types.size();
}
};
对数器
int types(std::vector<std::string> &arr) {
std::set<std::string> types;
for(auto str : arr){
int N = str.size();
std::vector<bool> map(26);
for (int i = 0; i < N ; ++i) {
map[str[i] - 'a'] = true;
}
std::string key;
for (int i = 0; i < 26; ++i) {
if(map[i]){
key += std::to_string((char)(i + 'a'));
}
}
types.emplace(key);
}
return types.size();
}
std::default_random_engine e;
std::string random_string(std::string::size_type length)
{
static auto& chrs =
"abcdefghijklmnopqrstuvwxyz";
thread_local static std::mt19937 rg{std::random_device{}()};
thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);
std::string s;
s.reserve(length);
while(length--)
s += chrs[pick(rg)];
return s;
}
std::vector<std::string> generateRandom(int maxVecLen, int maxStrLen){
std::uniform_int_distribution<int> distS(0, maxVecLen);
std::uniform_int_distribution<int> distV(0, maxStrLen);
int size = distS(e);
std::vector<std::string> ans(size);
for (int i = 0; i < size; ++i) {
ans[i] = random_string(distV(e));
}
return ans;
}
int main() {
e.seed(time(NULL));
int strMaxSize = 10;
int arrMaxSize = 100;
int testTimes = 500000;
Solution a;
printf("test begin, test time : %d\n" , testTimes);
for (int i = 0; i < 100; ++i) {
auto vec = generateRandom(arrMaxSize, strMaxSize);
int ans1 = a.types(vec);
int ans2 = types(vec);
if(ans1 != ans2){
printf("failed\n");
break;
}
}
printf("test finished, test time : %d\n" , testTimes);
return 0;
}