From d1a1f74d33921359631bee74b47c2f72c6b93dea Mon Sep 17 00:00:00 2001 From: Undumendil Date: Tue, 25 Jun 2019 19:05:24 +0300 Subject: [PATCH] Make string.index() use a linear KMP search --- builtin/string.v | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/builtin/string.v b/builtin/string.v index 54f93d0b79..9c656ad783 100644 --- a/builtin/string.v +++ b/builtin/string.v @@ -349,23 +349,36 @@ pub fn (s string) substr(start, end int) string { return res } +// KMP search pub fn (s string) index(p string) int { if p.len > s.len { return -1 } - mut i := 0 - for i < s.len { - mut j := 0 - mut ii := i - for j < p.len && s[ii] == p[j] { + mut prefix := [0] + mut j := 0 + for i := 1; i < p.len; i++ { + for p[j] != p[i] && j > 0 { + j = prefix[j - 1] + } + if p[j] == p[i] { + j++ + } + prefix << j + } + j = 0 + for i := 0; i < s.len; i++ { + for p[j] != s[i] && j > 0 { + j = prefix[j - 1] + } + if p[j] == s[i] { j++ - ii++ } if j == p.len { - return i + prefix.free() + return i - p.len + 1 } - i++ } + prefix.free() return -1 }