arrays - 在给定数组中查找整数序列

标签 arrays algorithm search go

我想知道是否有更好的方法(在我的实现正确的情况下)在给定数组中查找整数子序列。我已经使用 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
}

最佳答案

正确性

正如评论部分所讨论的,有一系列字符串匹配算法,通常分为单模式和多模式匹配算法。在您的情况下,它属于单一模式字符串匹配问题。

据我所知,最著名的算法是使用动态规划的 KMP 算法,以及一种名为 Rabin-Karp 的算法,它使用滚动哈希技术来加速该过程。两者都在 O(max(a,b)) 中运行。

但是,至少根据我的经验,您的代码与这些算法的正常实现不太相似。因此,我首先怀疑您的代码的正确性。您可以尝试像 a = {1, 2, 1, 2, 1}, b { 1, 1, 2, 2, 1, 2, 1 } 这样的情况,看看它没有给出正确的结果.

因此你可以

  1. 放弃当前算法并学习那些标准算法,实现它们
  2. 概述逻辑并草拟当前算法的证明,将其与那些标准算法背后的逻辑进行比较以验证其正确性

这部分留给你

复杂度

直接回答您的 OP:

不,O(max(a,b)) 是您在此问题中可以达到的最优值,这也是上述标准已知算法的复杂度。

我的理解是,它实际上是有道理的,因为在最坏的情况下,您必须至少读取较长字符串的每个字符 1 次。

您当前的算法显然也是 O(b),因为您使用 i 从 0 循环到 b 的长度,无论您属于 i 的条件将增加 1,总计为 O(b)


因此复杂性实际上不是问题,正确性才是问题。

关于arrays - 在给定数组中查找整数序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45181087/

相关文章:

Java - 为什么 StringBuffer 需要 base64 才能获得正确的十六进制?

c# - 如何找出最快的算法

javascript - 使用新的 ES6 Array.from() 方法

javascript 在嵌套函数中将项目添加到全局数组,更改不会反射(reflect)在使用 gmail api 的外部

algorithm - 可供使用的图表数据来源

algorithm - 检查顶点是否可达的算法

python-3.x - 使用单词列表中的最小单词子串形成目标字符串

search - 如何使用乌龟 git 搜索工具?

xml - 具有大量属性的 MarkLogic REST API 搜索

c++ - 将 QString 转换为无符号字符数组