Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion Clojure:nullpointerexception与递归_Recursion_Clojure_Nullpointerexception - Fatal编程技术网

Recursion Clojure:nullpointerexception与递归

Recursion Clojure:nullpointerexception与递归,recursion,clojure,nullpointerexception,Recursion,Clojure,Nullpointerexception,我正在创建一个重载函数,它将数字列表作为参数(以及重载签名中的数字列表和单个数字)。必须从该列表中找到并返回最高值。我知道可用的“sort”方法可以自动为您对列表进行排序,但我正在尝试使用递归发现最高值。下面是我正在使用的代码 32 (defn my-max 33 ([list] 34 (if (empty? list) 35 -1 36 (my-max (pop list) (first list))) ; recursive

我正在创建一个重载函数,它将数字列表作为参数(以及重载签名中的数字列表和单个数字)。必须从该列表中找到并返回最高值。我知道可用的“sort”方法可以自动为您对列表进行排序,但我正在尝试使用递归发现最高值。下面是我正在使用的代码

32    (defn my-max
33      ([list]
34        (if (empty? list)
35          -1
36          (my-max (pop list) (first list))) ; recursive call
37        )
38      ([list high]
39        (if (empty? list) ; base case
40          high)
41        (if (> (first list) high)
42          (my-max (pop list) (first list)))
43        (my-max (pop list) high))
44      )
45    
46    (println (my-max '(1 2 3)))
如您所见,我已经硬编码了一个包含1、2和3的列表,其中3应该被返回。运行代码时,我收到一个错误:

Exception in thread "main" java.lang.NullPointerException
    at clojure.lang.Numbers.ops(Numbers.java:942)
    at clojure.lang.Numbers.gt(Numbers.java:227)
    at user$my_max.invoke(HelloWorld.clj:41)
    at user$my_max.invoke(HelloWorld.clj:42)
    at user$my_max.invoke(HelloWorld.clj:42)
    at user$my_max.invoke(HelloWorld.clj:36)
    at user$eval2.invoke(HelloWorld.clj:46)
    at clojure.lang.Compiler.eval(Compiler.java:6619)
    at clojure.lang.Compiler.load(Compiler.java:7064)
    at clojure.lang.Compiler.loadFile(Compiler.java:7020)
    at clojure.main$load_script.invoke(main.clj:294)
    at clojure.main$script_opt.invoke(main.clj:356)
    at clojure.main$main.doInvoke(main.clj:440)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:415)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
此错误发生在最后一次递归调用中,其中3已从列表中“弹出”,并在列表为空且为“高”时传递回my max:

(if (empty? list) ; line 39, base case

应评估为真,但评估为假。你对这个问题有什么想法/解决办法吗?

那句话(第39-40行)没有任何作用。无论其计算结果是什么(无论是
还是
),都不会使用该值。然后第41行计算,如果列表为空,则
(第一个列表)
为零,因此出现空指针异常。

该语句(第39-40行)不起任何作用。无论其计算结果是什么(无论是
还是
),都不会使用该值。然后第41行求值,如果列表为空,则
(第一个列表)
为零,因此出现空指针异常。

the
the
Arthur Ulfeldt的回答指出括号放错了位置。Diego Basch的回答澄清了该问题是如何导致空指针异常的。我只是想指出,注意适当的自动缩进(您问题中的代码说明了这一点),可以立即看出括号有问题,因为应该是else子句的表达式缩进到与初始
完全相同的级别(如果
,因为您提到排序
是在数字列表中查找最大值的一种方法(不是很有效),注意clojure.core.Arthur Ulfeldt的回答指出括号放错了位置。Diego Basch的回答澄清了该问题是如何导致空指针异常的。我只想指出,注意正确的自动缩进(问题中的代码说明了这一点),可以立即看出括号有问题,因为应该是else子句的表达式缩进到与首字母
完全相同的级别(如果
。因为您提到
排序
,这是在数字列表中查找最大值的一种方法(不是很有效),除了使用正确的代码缩进的重要性之外,还要注意clojure.core,还应该注意的是,您应该使用recur,而不仅仅是递归地调用您的过程,因为Clojure没有尾部调用优化。recur将确保此函数能够与大型列表一起工作,在这些列表中,除了使用正确的代码缩进的重要性外,当前版本还可以非常快速地将堆栈吹出(我推荐一个支持使用s-exp和平衡参数等的编辑器),还应注意的是,您应该使用recur,而不仅仅是递归调用您的过程,因为Clojure没有尾部调用优化。recur将确保此函数能够在当前版本将很快耗尽堆栈的大型列表中工作
user> (defn my-max
       ([list]
         (if (empty? list)
          -1
           (my-max (pop list) (first list))))

       ([list high]
        (if (empty? list) ; base case
          high
         (if (> (or (first list) 0) (or high 0))
            (my-max (pop list) (first list))
            (my-max (pop list) high)))))
      #'user/my-max
      user> (println (my-max '(1 2 3)))
      3
      nil