/// <summary> /// 最長共通接頭辞の長さ /// S[l1:]とother.S[l2:] /// </summary> public int GetLcp(RollingHash other, int l1, int l2) { if (other == null) { throw new ArgumentNullException(nameof(other)); } int len = Math.Min(S.Length - l1, other.S.Length - l2); int low = -1, high = len + 1; while (high - low > 1) { var mid = low + (high - low) / 2; if (!Match(other, l1, l2, mid)) { high = mid; } else { low = mid; } } return(low); }
/// <summary> /// S[l1:]がotherで始まっているか /// </summary> public bool BeginWith(RollingHash other, int l1) { if (other == null) { throw new ArgumentNullException(nameof(other)); } return(Match(other, l1, 0, other.S.Length)); }
/// <summary> /// 全てのModsでS[l,r)が一致するか /// </summary> public bool Match(RollingHash other, int l1, int l2, int len) { if (other == null) { throw new ArgumentNullException(nameof(other)); } // 範囲外 if (S.Length < l1 + len || other.S.Length < l2 + len) { return(false); } for (int i = 0; i < _mods.Length; i++) { if (GetHash(l1, l1 + len, i) != other.GetHash(l2, l2 + len, i)) { return(false); } } return(true); }