我正在用Clojure编写一个作业,该作业应显示两个输入之间的素数列表:from
和to
。我设法通过以下功能做到了这一点:
(defn print-top-primes [ from to ]
(doseq
[ i (prime-seq from to) ] ;;prime-seq returns a range of numbers
(println i)
)
)
哪个给出输出:
(print-top-primes 50 100)
53
59
61
67
71
73
79
83
89
97
=> nil
但是,作业指定我需要这样打印数字:
(print-top-primes 50 100)
97
89
83
79
73
71
67
61
59
53
Total=732
=> nil
我无法使用doseq
从上到下打印数字。
我还需要添加所有素数的总和,但是由于doseq
函数不包含i
的每个值,因此我不确定这将如何工作。
也许我使用了错误的函数,但是赋值中的示例输出了:
=> nil
...暗示它是doseq
函数?
任何帮助将不胜感激。
谢谢
答案 0 :(得分:0)
一种简单的方法是:
(defn print-top-primes [from to]
(let [top-primes (reverse (prime-seq from to))
total (apply + top-primes)]
(doseq [i top-primes]
(println i))
(printf "Total = %d\n" total)))
=> (print-top-primes 50 100)
97
89
83
79
73
71
67
61
59
53
Total = 732
nil
如果您真的想避免在素数列表中进行三遍处理(一次用于reverse
,一次用于apply +
,而一次用于打印),则可以尝试以下操作:
(defn print-top-primes [from to]
(loop [primes (prime-seq from to)
total 0]
(let [p (last primes)]
(if p
(do (println p)
(recur (butlast primes) (+ total p)))
(printf "Total = %d\n" total)))))
但是您需要验证是否足以提高性能以证明增加的复杂性。
答案 1 :(得分:0)
谢谢你,
看着你的回答,我想到了一个更简单的方法,这就是我所教过的方法,所以我应该这样实现:
(defn print-top-primes [ from to ]
(doseq [i (reverse (prime-seq from to))]
(println i))
(printf "Total = %d\n" (reduce + (prime-seq from to)))
)
提供正确的输出!
我想知道既然存在大量素数,现在是否有办法只输出前10个最大素数?
答案 2 :(得分:0)
也许您的课程将在接下来提到它,但是无论如何我不会在这里使用doseq
和loop
:
recur
打印:
(loop [elements (reverse (range 10))
sum 0]
(if (empty? elements)
sum
(let [[head & tail] elements]
(println head)
(recur tail (+ sum head)))))
返回:
9
8
7
6
5
4
3
2
1
0
代替返回值,您可以轻松地编写所需的45
行并返回nil。
Total
宏允许定义累加器(如loop
)。我使用sum
表示法将元素的序列分解为两部分。反向序列只能遍历一次。
[returns nil] ...暗示这是一个剂量函数?
首先,[head & tail]
是一个宏,其次,有很多返回doseq
的方法,您无法猜测您所使用的示例是否在使用nil
。作业应告知您是否必须使用doseq
,也许您没有义务使用它。