我想知道是否有更好的方法(在我的实现是正确的情况下)在给定数组中找到整数的子序列。我已经使用golang实现了解决方案(如果这是审查的障碍,我可以使用不同的语言)。如果我没有弄错,波纹管的实现接近于O(b)。
package main
import "fmt"
func main() {
a := []int{1, 2, 3}
b := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
r := match(a, b)
fmt.Println("Match found for case 1: ", r)
a = []int{1, 2, 3}
b = []int{4, 5, 6, 7, 8, 9}
r = match(a, b)
fmt.Println("Match found for case 2: ", r)
a = []int{1, 2, 3}
b = []int{1, 5, 3, 7, 8, 9}
r = match(a, b)
fmt.Println("Match found for case 3: ", r)
a = []int{1, 2, 3}
b = []int{4, 5, 1, 7, 3, 9}
r = match(a, b)
fmt.Println("Match found for case 4: ", r)
a = []int{1, 2, 3}
b = []int{4, 5, 6, 1, 2, 3}
r = match(a, b)
fmt.Println("Match found for case 5: ", r)
a = []int{1, 2, 3}
b = []int{1, 2, 1, 2, 3}
r = match(a, b)
fmt.Println("Match found for case 6: ", r)
a = []int{1, 2, 3, 4, 5}
b = []int{4, 1, 5, 3, 6, 1, 2, 4, 4, 5, 7, 8, 1, 2, 2, 4, 1, 3, 3, 4}
r = match(a, b)
fmt.Println("Match found for case 7: ", r)
a = []int{1, 2, 1, 2, 1}
b = []int{1, 1, 2, 2, 1, 2, 1}
r = match(a, b)
fmt.Println("Match found for case 8: ", r)
}
func match(a []int, b []int) bool {
if len(b) < len(a) {
return false
}
lb := len(b) - 1
la := len(a) - 1
i := 0
j := la
k := 0
counter := 0
for {
if i > lb || j > lb {
break
}
if b[i] != a[k] || b[j] != a[la] {
i++
j++
counter = 0
continue
} else {
i++
counter++
if k < la {
k++
} else {
k = 0
}
}
if counter >= la+1 {
return true
}
}
return counter >= la+1
}
答案 0 :(得分:1)
如评论部分所述,有一系列字符串匹配算法,通常分为单模式和多模式匹配算法。在您的情况下,它属于单一模式字符串匹配问题。
据我所知,最着名的算法是使用动态编程的KMP算法,以及使用滚动哈希技术来加速该过程的另一种名为Rabin-Karp的算法。两者都在O(max(a,b))
中运行。
但是,您的代码与这些算法的正常实现不太相似,至少根据我的经验。因此,我首先怀疑代码的正确性。您可以尝试a = {1, 2, 1, 2, 1}, b { 1, 1, 2, 2, 1, 2, 1 }
之类的案例,看看它没有给出正确的结果。
因此你可以
我会把这部分留给你
直接回答您的OP:
不,O(max(a,b))
是您在此问题中可以实现的最佳选择,这也是上述标准已知算法的复杂性。
我的理解是,它实际上是有意义的,因为在最坏的情况下,你必须至少读取一次较长字符串的每个字符。
您当前的算法也明确O(b)
,因为您使用i
从0循环到b
的长度,无论您陷入i
的哪个条件都会增加1,总计O(b)
因此,复杂性实际上不是问题,正确性就是问题。
答案 1 :(得分:-1)
由于您只是在查找序列,我可能会将所有内容转换为字符串类型并使用标准字符串包。 Playground
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(strings.Contains("1, 2, 3, 4, 5, 6, 7, 8, 9", "1, 2, 3"))
fmt.Println(strings.Contains("4, 5, 6, 7, 8, 9", "1, 2, 3"))
fmt.Println(strings.Contains("1, 5, 3, 7, 8, 9", "1, 2, 3"))
fmt.Println(strings.Contains("4, 5, 1, 7, 3, 9", "1, 2, 3"))
fmt.Println(strings.Contains("4, 5, 6, 1, 2, 3", "1, 2, 3"))
fmt.Println(strings.Contains("4, 5, 6, 1, 2, 3, 2", "1, 2, 2, 3"))
fmt.Println(strings.Contains("1, 2, 1, 2, 3", "1, 2, 3"))
}