如何在 Clojure 中拆分一个数字?

How to split a number in Clojure?

我正在寻找一种在 Clojure 中用 n 数字拆分数字的好方法我有这两种方法:

 (->> (str 942)
      seq
      (map str)
      (map read-string)) => (9 4 2)

和...

(defn digits [n]
   (cons 
      (str (mod n 10)) (lazy-seq (positive-numbers (quot n 10)))))

(map read-string (reverse (take 5 (digits 10012)))) => (1 0 0 1 2)

这种操作有没有更简洁的方法?

你可以简单地做

(map #(Character/digit % 10) (str 942))

编辑:添加函数定义

(defn digits [number] (map #(Character/digit % 10) (str number)))

用法:

(digits 1234)

注意:这很简洁,但确实使用了 java 字符串和字符 类。可以使用整数模运算来编写高效的实现,但不会简洁。类似于 Charles 的答案的一种解决方案是:

(defn numTodigits
  [num]
  (loop [n num res []]
    (if (zero? n)
      res
      (recur (quot n 10) (cons (mod n 10) res)))))

Source

我不确定是否简洁,但这避免了不必要的低效率,例如转换为字符串并返回为整数。

(defn digits [n]
  (loop [result (list), n n]
    (if (pos? n)
      (recur (conj result (rem n 10))
             (quot n 10))
      result)))

一个递归实现(可能更高效,更不简洁,但对于合理的数字应该无关紧要)。

(defn digits [n]
  (when (pos? n)
    (concat (digits (quot n 10))
            [(mod n 10)])))

第一种方法的简明版本是

(defn digits [n]
  (->> n str (map (comp read-string str))))

...你的第二个是

(defn digits [n]
  (if (pos? n)
    (conj (digits (quot n 10)) (mod n 10) )
    []))

惯用的替代方法

(defn digits [n]
  (->> n
       (iterate #(quot % 10))
       (take-while pos?)
       (mapv #(mod % 10))
       rseq))

例如,

(map digits [0 942 -3])
;(nil (9 4 2) nil)
  • 计算本质上是急切的,因为 last 数字 in 。所以我们不妨使用mapvrseq(而不是mapreverse)来更快。
  • 该函数已准备好换能器。
  • 它只适用于正数。

一种循环方法:

 (defn split-numbers [number]
   (loop [itr 0 res [] n number]
     (if (= n 0)
       res
       (recur (inc itr) (concat (vector (mod n 10)) res) (int (/ n 10)))
       )
     )
   )

我能找到的最简单的:

(->> (str n)
   seq
   (map (comp read-string str)))