首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >方案中的Knuth-Morris-Pratt算法

方案中的Knuth-Morris-Pratt算法
EN

Stack Overflow用户
提问于 2020-08-18 18:54:43
回答 1查看 87关注 0票数 2

这是当我们使用Knuth-Morris-Pratt算法时,在Scheme中计算失败函数(我们需要返回多少步)的代码:

代码语言:javascript
复制
(define (compute-failure-function p)
    (define n-p (string-length p))
    (define sigma-table (make-vector n-p 0))
    (let loop
        ((i-p 2)
         (k 0))
      (cond
          ((>= i-p n-p)
           (vector-set! sigma-table (- n-p 1) k))
          ((eq? (string-ref p k)
                (string-ref p (- i-p 1)))
           (vector-set! sigma-table i-p (+ k 1))
           (loop (+ i-p 1) (+ k 1)))
          ((> k 0)
           (loop i-p (vector-ref sigma-table k)))
          (else ; k=0
           (vector-set! sigma-table i-p 0)
           (loop (+ i-p 1) k))))
    (vector-set! sigma-table 0 -1)
    (lambda (q)
        (vector-ref sigma-table q)))

但是我不明白当k > 0的时候的部分。有人能解释一下吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-18 23:54:44

我发现您对named let的语法感到困惑。这个post很好地解释了它是如何工作的,但也许使用更熟悉的语法的示例会让事情变得更清楚。以Python中的这段代码为例,它将1到10之间的所有整数相加:

代码语言:javascript
复制
sum = 0
n = 1
while n <= 10:
  sum += n
  n += 1

print(sum)
=> 55

现在让我们尝试以递归的方式编写它,我将把我的函数命名为loop。这是完全等价的:

代码语言:javascript
复制
def loop(n, sum):
    if n > 10:
        return sum
    else:
        return loop(n + 1, n + sum)

loop(1, 0)
=> 55

在上面的示例中,loop函数实现一次迭代,参数n用于跟踪当前位置,参数sum累积答案。现在让我们编写完全相同的代码,但在Scheme中:

代码语言:javascript
复制
(let loop ((n 1) (sum 0))
  (cond ((> n 10) sum)
        (else (loop (+ n 1) (+ n sum)))))
=> 55

现在,我们已经定义了一个名为loop的本地过程,然后会使用其参数nsum的初始值10自动调用该过程。当达到递归的基本情况时,我们返回sum,否则我们继续调用此过程,传递参数的更新值。它与Python代码中的代码完全相同!不要被语法搞糊涂了。

在您的算法中,i-pk是迭代变量,分别初始化为20。根据哪个条件为真,当我们使用i-pk的更新值再次调用loop时,迭代将继续,或者当达到case (>= i-p n-p)时迭代结束,此时循环退出,计算值在变量sigma-table中。该过程以返回一个新函数结束,该新函数称为“失败函数”。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63467134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档