在clojure中将数字从基数10转换为另一个基数

时间:2014-09-28 07:19:43

标签: clojure decimal

我应该编写一个包含2个参数的函数,将第一个数字从基数10转换为基数b。返回的值应该是一个集合。

我尝试使用格式,但如果b2,9,0等,我不知道如何使用它。

(defn f[x y]
   (cond
     (= y 8)(format "octal %o" x)
     (= y 16)(format "hex %x" x)
     (= y 10)(format "decimal %d" x) 
     :else 0))

4 个答案:

答案 0 :(得分:5)

鉴于这不是某种必要的练习 手动进行转换,您可以使用Java Integer.toString

e.g。

user> (Integer/toString 123456 13) ;; 123456 in base 13
"44268"

至于序列部分,你可以(seq (Integer/toString numb base) 但是,这将返回字符(0-9和a-z)。你可能会 想要一个查找函数来获取数字。

同时检查toString文档是否允许 基数。

另一方面,如果要求您手动转换 那么this MO文章可能是一个好的开始。

答案 1 :(得分:2)

(defn to-digits
  [n b]
  (loop [n n
         digits ()]
    (if (pos? n)
      (recur (quot n b)
             (conj digits (mod n b)))
      digits)))

答案 2 :(得分:2)

以下函数将执行转换,转换为java的BigInteger,因此它也适用于Integer/MAX_VALUE上的整数值(2147483647)

(defn to-radix
  [int r]
  (.toString (biginteger int) r))

(to-radix 255 2)
=> "11111111"

(defn from-radix
  [str r]
  (BigInteger. str r)

(from-radix "11111111" 2)
=> 255

字符串可以被视为字符集合。 map,filter,reduce等会调用seq来遍历它。在其他情况下,您可以自己致电seq

(seq (to-radix 255 2))
=> (\1 \1 \1 \1 \1 \1 \1 \1)

答案 3 :(得分:0)

这是我纯粹的Clojure解决方案:

(def charset "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

(def num->char
  (into {} (map-indexed vector charset)))

(def char->num
  (into {} (map-indexed (comp vec reverse vector) charset)))

(def base (count charset))

(def divmod (juxt quot rem))

(defn exp [x n]
  (loop [acc 1 n n]
    (if (zero? n) acc
        (recur (* x acc) (dec n)))))

(defn encode [n]
  (loop [n n a ""]
    (let [[div mod] (divmod n base)]
      (if (zero? div)
        (str (get num->char mod) a)
        (recur div (str (get num->char mod) a))))))

(defn decode-pair [idx chr]
  (* (get char->num chr)
     (exp base idx)))

(def sum (partial reduce +))

(defn decode [s]
  (sum (map-indexed decode-pair (reverse s))))

用法:

(encode 1000000000)
15FTGg

(decode "15FTGg")
1000000000

(-> 1000 encode decode (= 1000))
true