我真的很难做到这一功能。功能如下
写一个名为无因数的函数吗?这需要输入n。如果2和√之间的数字均不除n,则函数应返回true,否则返回false。该函数应同时使用get-divisors函数和除法?功能。 提示:您可能需要包装分隔线?匿名函数中的函数,以便您可以传递n的值。
这是我的get-divisors
函数:
(defn get-divisors [n]
(str (range 2 (inc (Math/floor (Math/sqrt n))))))
这是我的divides?
函数:
(defn divide [a b]
(zero? (mod a b)))
我尝试创建一种方法来尝试完成此任务,但是,很遗憾。
这是我尝试过的:
(defn no-divisors [n]
divide(n (get-divisors n)))
我收到了输出:
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn user/x (form-init5516475059937019181.clj:16)`
我有一个想法,我想与我分享如何创建此任务,但是,因为这是我第一次使用Clojure,所以我不太确定要实现此功能还是可能。非常抱歉,我使用了混合语法,只是到现在为止我还从未使用过Clojure,但这是我的草稿/蓝图:
(defn no-divisors [n]
resultsArray = []
def results((get-divisors n))
for results in get-divisors
resultsArray.append(results)
for i=results[0]; i< results.count; i++
divide(n i)
)
我可能走在正确的道路上,或者可能(最有可能)完全错误。对于我可能获得的任何/所有帮助,我深表感谢。只是一点说明,我的get-divisors
和divides?
函数都可以正常工作。
答案 0 :(得分:2)
首先,您不能像在其他语言中那样仅将括号放在代码中的任何位置。它们表示评估代码时Clojure(和其他形式)中特定的内容,即列表中的第一件事是动词。一个要调用的函数。嵌套方括号表示重复调用函数的结果。因此,如果您有一个函数alice
返回了这样的函数(请与我保持联系,我正试图解释您得到的错误;)):
(defn alice []
(fn [] :bob))
然后您可以这样称呼
(alice) ;; => #function[user/alice/fn--6930]
,它将返回您在其中创建的函数,您可以像这样调用该匿名函数:
((alice)) ;; => :bob
实际获得该函数的结果。道歉,如果这有点离谱,但是括号有意思,那就是导致您得到错误的原因:
ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn
这意味着您正在尝试将数字作为函数调用。 clojure.lang.IFn
是Clojure所说的“我期待的事情是可以作为函数调用的东西”的方式。通过java.lang.Long
,Clojure的均值是“数字”。 ClassCastException意味着我看到了一件事情,并期待着另一件事。因此,实际上,该错误试图说明的是您写了一个开放的括号(
,然后跟着一个叫数字而不是函数的名字。这似乎非常像您编写了divide(n (get-divisors n))
而不是(divide n (get-divisors n))
,因为在求值divide(n (get-divisors n))
时,它首先尝试求值divide
并发现这是一个函数,但并没有这样做。尝试调用它。然后,它查看下一个格式(n (get-divisors n))
,并尝试询问n
是什么,并发现它是一个数字,不能将其称为函数。有道理吗?
在您的伪代码中,您有一个数组,您可以在该数组中附加数据以收集结果,同时遍历循环以构建结果。这是解决问题的非常必要的方法,而不是Clojure试图鼓励您解决问题的方法。 Clojure倾向于学习着眼于以数据为中心的解决问题的方法。思考问题的一种方法是用英语表达问题的方式。给定一个数字n
,取所有小于其平方根的数字,然后检查是否将它们划分为n
。如果该列表为空,则返回true,否则返回false。在Clojure中,您可以编写:
(defn divide? [a b]
(zero? (mod a b)))
(defn no-divisors? [n]
(->> (range 2 n)
(take-while #(< (* % %) n))
(filter (partial divide? n))
empty?))
在这里,我们使用->>
宏获取2到n
之间的数字的惰性序列,然后使用take-while
将该序列限制为仅数字平方的序列小于n
。然后,我们使用divide?
函数检查每个对象是否均分为n,最后询问列表是否为empty?
。由于Clojure的序列是惰性的,因此在尝试使用empty?
评估结果之前,不会发生任何实际计算,该结果在到达序列中的元素时将停止。这使它比实际遍历整个列表来获得更大的n
效率。
希望这会有所帮助。
P.S。我不确定您对get-divisors
的实现是否正确。
答案 1 :(得分:0)
您必须在进行过程中测试您的工作。让我们看一下您的get-divisors
函数:
(defn get-divisors [n]
(str (range 2 (inc (Math/floor (Math/sqrt n))))))
让我们尝试一下:
=> (get-divisors 20)
"(2 3 4)"
这是一个字符串,而不是应该的数字集合。删除有害的str
呼叫:
(defn get-divisors [n]
(range 2 (inc (Math/floor (Math/sqrt n)))))
现在
=> (get-divisors 20)
(2 3 4)
好。和一个边缘情况,只是为了确保:
=> (get-divisors 16)
(2 3 4)
再次好!我们可以放心使用此功能。
现在,我们要找出该集合的 none 中是否存在某些错误。有一个方便的函数叫做not-any?
。例如,
=> (not-any? even? (range 1 100 2))
true
我们要确定的是n
的潜在除数是否没有实际除以n
。因此,函数的形状可能是...