无法理解 shorthand 回文代码
Can't understand shorthand code in palindrome
我无法理解这段代码,请向我解释一下 for 循环的第二行发生了什么。
#include <cstdio>
char s[5005000];
int h[5005000];
const int M=3;
int main() {
scanf("%s",s);
int a=0,b=0,p=1,v=0;
for(int i=0;s[i];++i){
a=a*M+s[i],b+=s[i]*p,p*=M;
if(a==b)v+=(h[i+1]=h[(i+1)>>1]+1);
}
printf("%d\n",v);
return 0;
}
使用ASCII
检查[0,i]区间内的字符串是否为回文
例如,如果字符串是 a2a
-------------------------
i = 0
--------------------------
a = a * M + str[0] = 97
b += str[0] * p = 97
p * = M -> p = 3
由于 a == b 则 h[1] = h[1>>1] + 1 = 1 且 v += h[1],因此 v = 1
------------ ------------------
i = 1
--------------------------
a = a * M + str[1] = 97*3 + 50 = 341
b += str[1] * p = 97 + 50*3 = 247
p * = M -> p = 9
因为 a != b 那么什么都不会发生
----------------------------
i = 2
----------------------------
a = a * M + str[2] = 341* 3 + 97 = 1120
b += str[2]*p = 247 + 97*9 = 1120
p *= M -> p = 27
由于 a == b 则 h[3] = h[3>>1] + 1 = 2 且 v += h[3],因此 v = 3
------------ ------------------
最后,v = 3
这行代码:
a=a*M+s[i],b+=s[i]*p,p*=M;
正在使用"comma operator"。逗号运算符计算左侧,丢弃结果,然后计算右侧和 returns 结果。
在此代码中,它与分号的作用完全相同。显然,这段代码的作者认为有一些理由在这里更喜欢逗号运算符而不是使用分号——我不同意,但这只是我的意见。
我无法理解这段代码,请向我解释一下 for 循环的第二行发生了什么。
#include <cstdio>
char s[5005000];
int h[5005000];
const int M=3;
int main() {
scanf("%s",s);
int a=0,b=0,p=1,v=0;
for(int i=0;s[i];++i){
a=a*M+s[i],b+=s[i]*p,p*=M;
if(a==b)v+=(h[i+1]=h[(i+1)>>1]+1);
}
printf("%d\n",v);
return 0;
}
使用ASCII
检查[0,i]区间内的字符串是否为回文
例如,如果字符串是 a2a
-------------------------
i = 0
--------------------------
a = a * M + str[0] = 97
b += str[0] * p = 97
p * = M -> p = 3
由于 a == b 则 h[1] = h[1>>1] + 1 = 1 且 v += h[1],因此 v = 1
------------ ------------------
i = 1
--------------------------
a = a * M + str[1] = 97*3 + 50 = 341
b += str[1] * p = 97 + 50*3 = 247
p * = M -> p = 9
因为 a != b 那么什么都不会发生
----------------------------
i = 2
----------------------------
a = a * M + str[2] = 341* 3 + 97 = 1120
b += str[2]*p = 247 + 97*9 = 1120
p *= M -> p = 27
由于 a == b 则 h[3] = h[3>>1] + 1 = 2 且 v += h[3],因此 v = 3
------------ ------------------
最后,v = 3
这行代码:
a=a*M+s[i],b+=s[i]*p,p*=M;
正在使用"comma operator"。逗号运算符计算左侧,丢弃结果,然后计算右侧和 returns 结果。
在此代码中,它与分号的作用完全相同。显然,这段代码的作者认为有一些理由在这里更喜欢逗号运算符而不是使用分号——我不同意,但这只是我的意见。