9 F2 c. ~* y. }' B" T- b$ t7 H* g: C) l, Z+ K
显然,上述代码段的复杂度是 O(n)。Shift-And 算法的时间复杂度是O(m+n)。1 X4 p( H! Y# M2 K6 G X
实际上,shift 算法通常比KMP 算法的匹配速度要快,因为计算机位并行运算是非常高效的。* J! j6 I7 L1 b1 h' A" b J9 R
2 `. u2 q% \; z2 \$ H注意:数组B 的大小是由字符集决定的,如果字符来自ASCII 码,字符的数值范围是0~127,数组大小是128 即可;否则,可能需要更大的数组B,或者自己构建字符到整数索引之间的散列关系。/ m0 E. |$ o& l
' a. D" y1 {8 y/ u4,Shift-Or 算法- |2 E) W" |: z; a+ @+ N
在Shift-And 中,对掩码D 的更新:D = (D << 1 | 1) & B[S[i] ;) X P6 H5 W/ C# v' E8 M& J7 Y* P7 K
每次更新D 都需要额外进行D 移位后与"1" 的"或"运算。这是由于我们要保证当字符S 在T[0] 处出现时,D[0] 一定要等于1,而D 向左移位后最低位是0。1 Y2 D8 ~! A% S% L! {( }" |7 ^
" M/ q; P2 J+ l- Z, d% J
如果将Shift-And 中核心的“与” 运算改为“或” 运算,可以节省这一个附加的“或1” 运算。这正是Shift-Or 所改进的地方。 5 @ N, ]* b( O. ~8 @: K- @, ZShift-Or 与Shift-And 的唯一区别在于,在Shift-Or 中,“有效位” 是通过0(而不是1)来标识。 ( C7 s# G+ _7 K. `. H K: _于是求解辅助表B 和更新掩码D 都会与Shift-And 有一些区别,详见代码。, @, N! W- e! L# C
2 r; I- N/ N$ G- g' d8 F: Y7 ]3 p+ z
Shift-And 完整代码:C++ 实现Python 实现- G6 ]! O# a9 m. l8 A: h
Shift-Or 完整代码:C++ 实现Python 实现0 }' o& H9 _# R
+ {1 E, U. L5 S3 I