给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 。
请你返回 words 数组中 一致字符串 的数目。
示例 1:
输入:allowed = "ab", words = ["ad","bd","aaab","baa","badab"]
输出:2
解释:字符串 "aaab" 和 "baa" 都是一致字符串,因为它们只包含字符 'a' 和 'b' 。
示例 2:
输入:allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"]
输出:7
解释:所有字符串都是一致的。
示例 3:
输入:allowed = "cad", words = ["cc","acd","b","ba","bac","bad","ac","d"]
输出:4
解释:字符串 "cc","acd","ac" 和 "d" 是一致字符串。
提示:
1 <= words.length <= 104
1 <= allowed.length <= 26
1 <= words[i].length <= 10
allowed 中的字符 互不相同 。
words[i] 和 allowed 只包含小写英文字母。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-the-number-of-consistent-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解一:
循环迭代中 一次循环满足,就可以计数器++ 还是需要遍历循环全员满足才能计数器++(全员满足需要格外计数器辅助判断,每一次满足计数器+1,结束循环后计数器数目=全体成员数目(通常为数组大小或者字符串长度)说明全员满足条件,最终的计数器+1。
类似十进制,满10进1。
class Solution {
public:
int countConsistentStrings(string allowed, vector<string>& words) {
int count2 = 0;
for (auto && word : words) { //把words数组中的每个元素拉出来遍历
int count1 = 0;
for (auto && c1 : word) { //把这个word中的每个字符再拉出来遍历
for (auto && c2 : allowed) {//将这个word中的字符挨个与allowed中的字符一个一个比较
if (c1 == c2) { //看看word中有几个字符与allowed中的字符相同,字符相同,count1++,
count1++;
break;
}
}
}
if (count1 == word.length()) {//看来word中所有的字符都是属于allowed的,count2++(全员满足才能++)
count2++;
}
}
return count2; //遍历完成,返回count2
}
};
解二:
为26个字母设置32位整数进行位运算
class Solution {
public:
int countConsistentStrings(string allowed, vector<string>& words) {
int mask = 0; //为allowed设置一个32位int整数 准备对其进行位运算。
for (auto c : allowed) { // auto 类型转换 + 遍历allowed
mask |= 1 << (c - 'a'); // 在32位 二进制中,如果遍历过程中出现字母,则(利用ASCII码转换)对应的位置上设为1
}
int res = 0; // 设置计数器
for (auto &&word : words) { //
int mask1 = 0; // 设置一个32位整数 准备进行位运算
for (auto c : word) {
mask1 |= 1 << (c - 'a'); // 出现字母对应的位设为1
}
if ((mask1 | mask) == mask) { // 对两个32位整数进行 位或 运算 取交集,若交集为allowed则满足题意。计数器++
res++;
}
}
return res;
}
};
知识补充:
位运算 符号:&、 | 和 ^ (~取反)、(<<左移 、>>右移)
结果:
与赋值结合:
auto的用法 👈点击连接
auto、auto&、auto&&、const auto和const auto&的区别:
for(auto x : vector)
auto会拷贝一份容器内的vector,在修改x时不会改变原容器当中的vector值,只会改变拷贝的vector。
因为拷贝发生在编译期间,所以并不会对运行速率造成很大影响。
for(auto& x : vector)
当需要对原数据进行同步修改时,就需要添加&,即vector的引用。
会在改变x的同时修改vector。
for(auto&& x : vector)
当vector返回临时对象,使用auto&会编译错误,临时对象不能绑在non-const l-value reference (左值引用)需使用auto&&,初始化右值时也可捕获
for(const auto& x : vector)
const (常类型),不能作为左值
& (引用),不拷贝,不申请新空间,会对原vector修改
当我们不希望拷贝原vector(拷贝需要申请新的空间),同时不愿意随意改变原vector,那么我们可以使用for(const auto& x : vector),这样我们可以很方便的在不拷贝的情况下读取vector,同时不会修改vector。一般用在只读操作。
const auto x : vector
该操作相对于const auto& x : vector只是少了引用(&),即会申请新的空间(拷贝),不经常使用。
C++中coutinue 与 break 的区别: 👈原文链接
C++中continue和break语句的区别 break 和 continue 是相同类型的语句,专门用于改变程序的正常流程,但它们之间仍有一些区别。
- break 语句 :break 语句终止最小的封闭循环 (即 while、do-while、for 或 switch 语句)
- Continue 语句: continue 语句跳过循环语句的其余部分并导致循环的下一次迭代发生。
一个循环的退出应该通过循环顶部的条件测试来控制,就像在 while 循环或 for 循环中那样,或者在底部,就像在 do-while 循环中那样。
通常在循环中使用 break 语句的唯一时间是在发生错误的情况下提前退出循环。
有时候可能想要保持循环,但又想让当前迭代立即结束,这时可以通过 continue 语句来完成。
当遇到 continue 时,出现在它之后的循环体中的所有语句都被忽略,循环准备下一次迭代。在 while 循环中,这意味着程序跳转到循环顶部的测试表达式。如果表达式仍然为 true,则下一次迭代开始,否则,循环退出。在 do-while 循环中,程序跳转到循环底部的测试表达式,它决定下一次迭代是否开始。在 for 循环中,continue 会导致更新表达式被执行,然后测试表达式被评估。
C++ 中size()与sizeof()的区别:👈点击连接
sizeof(a)返回的是对象占用内存的字节数,而a.size()是string类定义的一个返回字符串大小的函数,两个是完全不一样的概念。
明确两者的概念和作用:
1、size()函数:
c++中,在获取字符串长度时,size()函数与length()函数作用相同。 除此之外,size()函数还可以获取vector类型的长度。
例如:vector < int> num(15,2) ,则:num.size() = 15。
2、sizeof():
sizeof()运算符用来求对象所占内存空间的大小。
sizeof(...)是运算符,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。
它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。
size是由string vector 和bitset定义的函数,分别用于返回字符个数,元素个数和二进制位的数。string和vector的size成员函数用以返回size_type类型的值。bitset返回size_t的值。