Clojure:doseq函数从上至下打印数字范围

时间:2018-12-20 21:18:48

标签: clojure

我正在用Clojure编写一个作业,该作业应显示两个输入之间的素数列表:fromto。我设法通过以下功能做到了这一点:

(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函数?

任何帮助将不胜感激。

谢谢

3 个答案:

答案 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)

也许您的课程将在接下来提到它,但是无论如何我不会在这里使用doseqloop

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,也许您没有义务使用它。