【问题标题】:Recursive function has bad performance递归函数性能不佳
【发布时间】:2020-06-23 07:51:08
【问题描述】:

我正在学习 clojure,我正在做一些练习来练习。目前我正在处理the next problem:

精灵通过高度安全的紧急渠道与您联系。回到 北极,精灵们忙着误会白象 派对。每个精灵都会带来一份礼物。他们都围成一圈,编号 从位置 1 开始。然后,从第一个精灵开始,他们采取 转身从他们左边的精灵那里偷走所有的礼物。一个精灵 没有礼物的会从圈子中移除,并且不会轮流。

例如,有五个精灵(编号为 1 到 5):

     1

5        2

   4 3

精灵 1 带走了精灵 2 的礼物。精灵 2 没有礼物,被跳过。精灵 3 带走了精灵 4 的礼物。精灵 4 没有礼物,也被跳过了。 精灵 5 拿走了精灵 1 的两个礼物。 Elf 1 和 Elf 2 都没有 礼物,所以两者都被跳过。精灵 3 拿走了精灵 5 的三个礼物。所以, 有五个精灵,从位置 3 开始的精灵获得所有 礼物。

在你的拼图输入中给出的精灵数量,精灵得到 所有的礼物?

我的代码:

(ns elfos-navidad.core (:gen-class))

(def elfs (range 8977))

(defn remove-elf [elfs] 
  (if (= (count elfs) 1) 
    elfs
    (let [[first second & rest] elfs]
      (recur (concat rest (list first))))))

(defn -main [& args]
  (time (println (+ 1 (first (remove-elf elfs))))))

我的片段可以正常工作,但是速度太慢了。 nodejs中的同样问题非常快。

PS:我知道解决这个问题的最好方法是使用链表,但我还不知道如何使用 clojure 来解决

【问题讨论】:

    标签: clojure


    【解决方案1】:

    问题是concat 在这里效率低下。如果您使用向量,有一种更好的方法可以将项目添加到集合的末尾:

    (defn remove-elf-v [elfs]
      (let [elfs (vec elfs)]
        (if (= (count elfs) 1) 
          elfs    
          (recur (conj (subvec elfs 2) (first elfs))))))
    
    user> (time (println (+ 1 (first (remove-elf-v elfs)))))
    ;;=> 1571
    ;;=> "Elapsed time: 20.128779 msecs"
    

    旧的:

    user> (time (println (+ 1 (first (remove-elf elfs)))))
    ;;=> 1571
    ;;=> "Elapsed time: 3482.966943 msecs"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      • 2021-08-02
      • 2021-02-07
      • 1970-01-01
      • 2015-03-01
      • 2018-06-17
      相关资源
      最近更新 更多