Exception Clojure在二进制搜索结束时抛出了这个错误。为什么?如何避免呢?
下面是代码,它是一个直接的二进制搜索实现Exception Clojure在二进制搜索结束时抛出了这个错误。为什么?如何避免呢?,exception,clojure,Exception,Clojure,下面是代码,它是一个直接的二进制搜索实现 (defn binary_search "searches for a single element in a sorted array in logartihmic time" ([array start end element] (do (println "start " start " end " end " middle " (int (+ (/ (- end start)
(defn binary_search
"searches for a single element in a sorted array in logartihmic time"
([array start end element]
(do (println "start " start " end " end " middle " (int (+ (/ (- end start) 2) start))) (
(if (= (get array (int (+ (/ (- end start) 2) start))) element) (println "element found at " (+ (int (/ (- end start) 2)) start))
(if (= (- end start) 0) (do (println "not found :(") -1)
(if (> (get array (+ (int (/ (- end start) 2)) start)) element) (binary_search array start (dec (+ (int (/ (- end start) 2)) start)) element)
(binary_search array (inc (+ (int (/ (- end start) 2)) start)) end element))
)))))
([array element] (do (println "starting binary search....") (binary_search array 0 (dec (count array)) element)))
)
我收到的错误是在每次函数执行结束时。如您所见,如果找到元素,它将输出NullPointerException,如果未找到元素,则输出ClassCastException
我的想法是,它试图将返回值作为一个函数执行,而当找不到元素时,返回值就不是了
并且,当它被找到时,它并没有返回预期的正确值,并且它正在尝试执行之后的语句,从而导致NPE。是这样吗
=> (Clojure-First.core/binary_search [1 2 3 4 5 6 7 8] 7)
starting binary search....
start 0 end 7 middle 3
start 4 end 7 middle 5
start 6 end 7 middle 6
element found at 6
NullPointerException Clojure-First.core/binary-search (core.clj:49)
=> (Clojure-First.core/binary_search [1 2 3 4 5 6 7 8] 8)
starting binary search....
start 0 end 7 middle 3
start 4 end 7 middle 5
start 6 end 7 middle 6
start 7 end 7 middle 7
element found at 7
NullPointerException Clojure-First.core/binary-search (core.clj:49)
=> (Clojure-First.core/binary_search [1 2 3 4 5 6 7 8] 1)
starting binary search....
start 0 end 7 middle 3
start 0 end 2 middle 1
start 0 end 0 middle 0
element found at 0
NullPointerException Clojure-First.core/binary-search (core.clj:49)
=> (Clojure-First.core/binary_search [1 2 3 4 5 6 7 8] 2)
starting binary search....
start 0 end 7 middle 3
start 0 end 2 middle 1
element found at 1
NullPointerException Clojure-First.core/binary-search (core.clj:49)
=> (Clojure-First.core/binary_search [1 2 3 4 5 6 7 8] 3)
starting binary search....
start 0 end 7 middle 3
start 0 end 2 middle 1
start 2 end 2 middle 2
element found at 2
NullPointerException Clojure-First.core/binary-search (core.clj:49)
=> (Clojure-First.core/binary_search [1 2 3 4 5 6 7 8] 17
)
starting binary search....
start 0 end 7 middle 3
start 4 end 7 middle 5
start 6 end 7 middle 6
start 7 end 7 middle 7
not found :(
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn Clojure-First.core/binary-search (core.clj:49)
在此代码摘录中:
...(
(if (= (get array (int...
您正在调用该条件的结果,就好像它是一个函数一样。代码很难阅读,但我看不到任何迹象表明它返回一个没有参数的函数
请尝试使用惯用的风格,特别是这段代码在绑定和换行时更具可读性
简单的修复方法是在挂起的大括号处添加对println或其他无害函数的调用:
...(println
(if (= (get array (int...
更好的方法是实际生成可读且惯用的Clojure代码:
(defn binary-search
"searches for a single element in a sorted array in logartihmic time"
([array start end element]
(let [middle_exact (+ (/ (- end start) 2) start)
middle (int middle_exact)
middle-elt (get array (int middle))]
(println "start " start " end " end " middle " middle)
(cond
(= middle-elt element)
(do (println "element found at " middle) middle)
(or (= end middle) (= start middle))
(do (println "not found :(") -1)
(> middle-elt element)
(recur array start (int (Math/floor (- end (/ middle_exact 2)))) element)
:otherwise
(recur array (int (Math/ceil (+ start (/ middle_exact 2)))) end element))))
([array element]
(println "starting binary search....")
(binary-search array 0 (dec (count array)) element)))
在此代码摘录中:
...(
(if (= (get array (int...
您正在调用该条件的结果,就好像它是一个函数一样。代码很难阅读,但我看不到任何迹象表明它返回一个没有参数的函数
请尝试使用惯用的风格,特别是这段代码在绑定和换行时更具可读性
简单的修复方法是在挂起的大括号处添加对println或其他无害函数的调用:
...(println
(if (= (get array (int...
更好的方法是实际生成可读且惯用的Clojure代码:
(defn binary-search
"searches for a single element in a sorted array in logartihmic time"
([array start end element]
(let [middle_exact (+ (/ (- end start) 2) start)
middle (int middle_exact)
middle-elt (get array (int middle))]
(println "start " start " end " end " middle " middle)
(cond
(= middle-elt element)
(do (println "element found at " middle) middle)
(or (= end middle) (= start middle))
(do (println "not found :(") -1)
(> middle-elt element)
(recur array start (int (Math/floor (- end (/ middle_exact 2)))) element)
:otherwise
(recur array (int (Math/ceil (+ start (/ middle_exact 2)))) end element))))
([array element]
(println "starting binary search....")
(binary-search array 0 (dec (count array)) element)))
正如noisesmith所建议的,NPE的原因是您试图对nil执行函数应用程序,nil是println的返回值 我只是想整理一下代码
(defn binary-search
"Searches for a single element in a sorted vector in logarithmic time,
and returns the index of the element if it exists, otherwise returns nil"
([v elem]
;(println "starting binary search....")
(binary-search v 0 (count v) elem))
([v start end elem]
(let [index (+ start (quot (- end start) 2))]
;(println 'start start 'end end 'middle index)
(if (<= start index (dec end))
(let [mid (nth v index)]
(cond (> mid elem) (recur v start index elem)
(< mid elem) (recur v (inc index) end elem)
:else index))
nil))))
如果要跟踪执行,请删除“;”在注释掉的行的开头。正如noisesmith所建议的,NPE的原因是您试图对nil执行函数应用,nil是println的返回值 我只是想整理一下代码
(defn binary-search
"Searches for a single element in a sorted vector in logarithmic time,
and returns the index of the element if it exists, otherwise returns nil"
([v elem]
;(println "starting binary search....")
(binary-search v 0 (count v) elem))
([v start end elem]
(let [index (+ start (quot (- end start) 2))]
;(println 'start start 'end end 'middle index)
(if (<= start index (dec end))
(let [mid (nth v index)]
(cond (> mid elem) (recur v start index elem)
(< mid elem) (recur v (inc index) end elem)
:else index))
nil))))
如果要跟踪执行,请删除“;”在行首注释掉。嘿,您的代码在执行时仍会抛出NPE。这并不能解决我的问题,它只是使代码更干净。仔细检查代码,我确实看到end元素中的end元素是无关的,应该删除,但由于前面的原因:否则代码永远不会到达那里。你正在运行哪个版本的Clojure?我在tryclj.com上看到这个错误-。在本地我得到了这个结果-这是搜索索引选择中的一个逻辑错误-我试图对现有逻辑进行直译,但它再次被错误地更新,这次检查了每个索引,对于不存在的元素,无论何时执行,您的代码都会抛出NPE。这并不能解决我的问题,它只是使代码更干净。仔细检查代码,我确实看到end元素中的end元素是无关的,应该删除,但由于前面的原因:否则代码永远不会到达那里。你正在运行哪个版本的Clojure?我在tryclj.com上看到这个错误-。在本地我得到了这个结果-这是搜索索引选择中的一个逻辑错误-我试图对现有逻辑进行直译,但它再次被错误地更新,这次检查了每个索引和不存在的元素