逐位比较
Bitwise comparisions
#include <iostream>
using namespace std;
int main() {
int n, a = 0xfffffff;
cin >> n;
while (n--) {
string s;
cin >> s;
int c = 0;
for (char ch : s)
c |= 1 << (ch - 'a');
a &= c;
}
cout << __builtin_popcount(a) << endl;
return 0;
}
该代码用于查找一个字符是否至少出现在所有输入字符串中一次。有人能解释一下这个代码中发生了什么吗。我正在努力学习C++中的逐位运算,但我无法理解这里发生了什么。
代码不是用来确定是否在所有字符串中都存在特定字符。
它是查找所有字符串中存在的字符数。
这是代码的分解。
int n, a = 0xfffffff;
cin >> n;
n是用户的输入参数,用于确定字符串的数量。假设n是3
while (n--) {
string s;
cin >> s;
int c = 0;
for (char ch : s)
c |= 1 << (ch - 'a');
a &= c;
}
这是代码的主要部分。。
你得到n个字符串,每个字符串都存储它由哪些字符组成,在一个位数组中
例如,让我们说第一个字符串是"堆叠";。你循环浏览这里的字符
for (char ch : s)
c |= 1 << (ch - 'a');
对于每个字符串,c被初始化为0。
在这个例子中;堆叠";,让我们看看c 发生了什么
c=c|1<lt;('s-'a')=>c=c|1<lt;18(c的第18位设置为1)
c=c|1<lt;(不是'-'a')=>c=c|1<lt;19(c的第19位设置为1)
c=c|1<lt;('a'-'a')=>c=c|1<lt;0(c的第0位设置为1)
c=c|1<lt;('c'-'a')=>c=c|1<lt;2(c的第2位设置为1)
c=c|1<lt;('k'-'a')=>c=c|1<lt;10(c的第10位设置为1)
注意,1<lt;n表示1被左移了n位数字。所以1<lt;3是=0001<lt;3=二进制1000=2^3=8(如果您不了解换档)
现在c是一个整数,其0,2,10,18,19位设置为1。a在循环之前被初始化为所有的1。
a&=c这去掉了除0、2、10、18和19之外的所有1。
我们继续对所有字符串执行此操作。并且在最后,a将在所有串中占据的位置设置1位。。
例如,如果字符串2是";aaaaa";
计算c表明c只有它的第0位集。
a&=c这去掉了除0之外的所有1(即,它将2、10、18和19位设置为0,因为它们不出现在"aaaaa"中)
并且字符串3是"0";zzzzz a";,最后,只有a的第0位将被设置为
因此,所有这些字符串中出现的字符数为1
这里没有太多内容,一点一点地分解可以揭示它的作用:
#include <iostream>
using namespace std;
int main() {
// Initialize a bitmask, here assumed to be 32-bits
// which is probably "enough" for this case.
int n, a = 0xfffffff;
// Read in the number of strings to process
cin >> n;
// Assume n > 0
while (n--) {
string s;
// Read in a string
cin >> s;
int c = 0;
// For each character in this string
for (char ch : s)
// Turn on a bit on representing the character, where
// 'a' is bit 0, 'b' is 1, etc.
c |= 1 << (ch - 'a');
// Apply this mask to a
a &= c;
}
// Report on which bits are toggled
cout << __builtin_popcount(a) << endl;
return 0;
}
总的来说,这是一些非常草率的代码。任何非小写字母都可能导致未定义的行为。对于现代机器来说,大多数编译器都是64位的,因此仅设置32位可能不够。
请注意,当我在这里使用"假设"一词时,我的意思是坏事可能会发生。
让我们先来看看
int c = 0;
for (char ch : s)
c |= 1 << (ch - 'a');
您可以使用变量c按位表示输入字符串的字符:
- 如果字符串中出现字符a,则变量c中的位0设置为1
- 如果字符串中出现字符b,则变量c中的第1位设置为1
- 如果字符串中出现字符c,则变量c中的第2位设置为1
- 等等
c中的所有其他位均为零。
完成一个字符串后,代码
a &= c;
被执行。此代码将变量a中的一个位设置为1,如果它之前是1,则c的相应位也是1。然后,函数继续读取下一个字符串,并再次执行相同操作。
在执行结束时,a的那些位恰好被设置为1,在while块中的所有c中都是1。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么比较运算符如此快速
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 比较字符数组
- 将模板化的类型与C++中的某些类/类型进行比较
- C++自定义比较函数
- 如何比较自定义类的std::变体
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- std::设置自定义比较器
- 布尔比较运算符是如何在C++中工作的
- C++将目录中的所有文件与::filesystem进行比较
- shell排序中的交换和比较
- 如何在C++中比较两个char数组
- catch框架有没有办法比较流或文件
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 智能指针作为无序映射键,并通过引用进行比较
- 比较if语句中的数组值和int值
- 对于循环变体比较
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 比较两个大小不等的映射c++