#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 ++学习一些明智的操作,但我无法理解这里发生的事情。
答案 0 :(得分:6)
代码不是要确定所有字符串中是否存在特定字符。
找到所有字符串中存在的字符数。
这是代码的细分。
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个字符串,并且对于每个字符串,你用一个数组
存储它由它组成的字符例如,让我们说第一个字符串是&#34; stack&#34;。你遍历这里的人物
for (char ch : s)
c |= 1 << (ch - 'a');
对于每个字符串,c初始化为0。
在这个例子&#34; stack&#34;中,让我们看看c
会发生什么c = c | 1&lt;&lt; (&#39; s&#39; - &#39; a&#39;)=&gt; c = c | 1&lt;&lt; 18(c的第18位设为1)
c = c | 1&lt;&lt; (&#39; t&#39; - &#39; a&#39;)=&gt; c = c | 1&lt;&lt; 19(c的第19位设为1)
c = c | 1&lt;&lt; (&#39; a&#39; - &#39; a&#39;)=&gt; c = c | 1&lt;&lt; 0(c的第0位设置为1)
c = c | 1&lt;&lt; (&#39; c&#39; - &#39; a&#39;)=&gt; c = c | 1&lt;&lt; 2(c的第2位设为1)
c = c | 1&lt;&lt; (&#39; k&#39; - &#39; a&#39;)=&gt; c = c | 1&lt;&lt; 10(c的第10位设置为1)
注意1 <&lt;&lt; n表示1左移n位数。所以1&lt;&lt; 3是= 0001&lt;&lt; 3 =二进制1000 = 2 ^ 3 = 8(如果你不理解转移)
现在c是一个整数,其0,2,10,18,19位设置为1. a被初始化为循环前的所有1。
a&amp; = c;这除掉了0,2,10,18和19之外的所有1。
我们继续为所有字符串。最后,a将在所有字符串占用的位置设置1位..
例如,如果字符串2是&#34; aaaaa&#34;
计算c显示c只有第0位设置。
a&amp; = c;这除掉了0以外的所有1(即,它将2,10,18和19位设置为0,因为它们不会出现在&#34; aaaaa&#34;)
和字符串3是&#34; zzzzza&#34;,最后,只会设置第0位
因此,所有这些字符串中出现的字符数为1
答案 1 :(得分:2)
这里没有多少事情发生,并且一点一点地分解它会发现它的作用:
#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;
}
总的来说,这是一些严重邋code的代码。任何非小写字母都可能导致未定义的行为。对于现代机器,大多数编译器都是64位的,因此只设置32位可能是不够的。
请注意,当我使用单词&#34;假设&#34;在这里,我的意思是可能会发生坏事。
答案 2 :(得分:1)
我们先来看看
int c = 0;
for (char ch : s)
c |= 1 << (ch - 'a');
使用变量 c 按位代表输入字符串的字符:
c 中的所有其他位均为零。
完成一个字符串后,代码
a &= c;
被执行。此代码将变量 a 中的位设置为1,如果之前为1,则 c 中的相应位也为1。然后函数继续读取下一个字符串并再次执行相同操作。
执行结束时, a 的那些位设置为1,而在while块中的所有 c 中为1。