2012-08-22 70 views
6

我想生成0到2^n-1的n數字的二進制數。例如3位數,「000」,「001」,「010」,...,「111」(十進制0到7)。我使用的方法是使用java.lang.Integer.toBinaryString()方法,必要時添加零如下所示:在clojure中生成n位數的二進制數

(defn pad-zero [s n] 
    (str (reduce str (repeat (- n (count s)) "0")) s)) 

(defn binary-permutation [n] 
    (map (fn [s] (pad-zero s n)) 
     (map #(Integer/toBinaryString %) (range 0 (Math/pow 2 n))))) 

有了這個代碼,我可以生成什麼,我想是這樣的。 3位數字:

(binary-permutation 3) 
=> ("000" "001" "010" "011" "100" "101" "110" "111") 

但是這段代碼看起來有點冗長。 有沒有更好的或更clojure方式來做到這一點?

回答

7

您可以從clojure.pprint簡化使用cl-format格式:

(defn binary-permutation [n] 
    (map (partial cl-format nil "~v,'0B" n) (range 0 (Math/pow 2 n)))) 

您可能也有興趣知道,(Math/pow 2 n)相當於(bit-shift-left 1 n)

另一種方式來表達,這將是在selections期限爲clojure.math.combinatorics

(defn binary-permutation [n] 
    (map (partial apply str) (selections [0 1] n))) 
+0

爲什麼用'CL-format'? – noahlz

+1

@noahz cl-format是來自Common Lisp的輸出格式化函數,可在Clojure中使用(類似於其他語言的printf)。它只是讓OP更容易輸出填充的二進制數字。保存擊鍵。如果您有其他選擇,也可隨意發佈。 –

+1

@noahz如果你問爲什麼使用這個函數的一個版本而不是其他版本。我不確定。我想說基於範圍的版本有點簡單。它只是在計數。但是組合解決方案也很有趣。 –

2
(defn binary-permutation [n] 
    (for [x (range (Math/pow 2 n))] 
    (apply str (reverse (take n (map #(bit-and 1 %) (iterate #(bit-shift-right % 1) x))))))) 

(defn pad-zero [s n] 
    (apply str (take-last n (concat (repeat n \0) s))))