Levenshtein在Clojure中的实现

Levenshtein在Clojure中的实现,clojure,memoization,levenshtein-distance,Clojure,Memoization,Levenshtein Distance,这是使用Clojure和递归的最小(编辑距离)实现: (defn levenshtein [s1, i1, s2, i2] (cond (= 0 i1) i2 (= 0 i2) i1 :else (min (+ (levenshtein s1 (- i1 1) s2 i2) 1) (+ (levenshtein s1 i1 s2 (- i2 1)) 1) (+ (levenshtein s1 (- i1 1) s2 (- i

这是使用Clojure和递归的最小(编辑距离)实现:

(defn levenshtein [s1, i1, s2, i2]
  (cond
    (= 0 i1) i2
    (= 0 i2) i1
    :else
    (min (+ (levenshtein s1 (- i1 1) s2 i2) 1)
         (+ (levenshtein s1 i1 s2 (- i2 1)) 1)
         (+ (levenshtein s1 (- i1 1) s2 (- i2 1)) (if (= (subs s1 i1 (+ i1 1)) (subs s2 i2 (+ i2 1))) 0 1))
         )
    )
  )

(defn levenshteinSimple [s1, s2]
  (levenshtein s1, (- (count s1) 1), s2, (- (count s2) 1)))
可以这样使用:

(println (levenshteinSimple "hello", "hilloo"))
(println (levenshteinSimple "hello", "hilloo"))
(println (levenshteinSimple "bananas", "bananas"))
(println (levenshteinSimple "ananas", "bananas"))
然后打印这个:

2
2
0
1
如何将memoize添加到此实现中以提高性能


请注意:我是Clojure初学者。这是我在Clojure中的第一行

最简单的方法就是使用
memoize
函数。它接受一个函数,并返回一个已记忆的函数:

(let [mem-lev (memoize levenshteinSimple]
  (println (mem-lev "hello", "hilloo"))
  (println (mem-lev "hello", "hilloo"))
  (println (mem-lev "bananas", "bananas"))
  (println (mem-lev "ananas", "bananas")))
mem-lev
将记住您给出的每个参数以及函数返回的结果,如果已经看到您给出的参数,则将返回缓存结果

注意,这不会导致递归调用被记忆化,但是任何递归调用都不可能从记忆化中获益

这也不会导致您的原始功能被记忆。在本例中,只有
mem-lev
将被记忆。如果您真的想记住全局函数,您可以将定义更改为:

(def levenshteinSimple
  (memoize
    (fn [s1, s2]
      ...
但我不建议这样做。这会导致函数本身保持状态,这并不理想。它还会在程序的整个过程中保持这种状态,如果被滥用,可能会导致内存问题


(作为一个很好的练习,试着编写自己版本的
memoize
。这样做我学到了很多东西)

非常感谢。我将研究创建自己的版本。目前,我仍在努力学习语法。@gil.fernandes lisps一开始很难,因为它们的语法与大多数其他语言非常不同。坚持下去,你就会开始欣赏它的简单。确保你正在使用一个程序来管理你的牙套。我在IDE中使用IntelliJ,并使用草书插件,这样我就可以在Clojure中使用它。草书有“par推断”功能,所以我不必手动管理所有的右大括号。我只是像在Python中一样缩进我的代码,它用它来为我关闭所有的大括号。锻炼建议可能需要等一等。给它一两个月的时间。