2012-10-27 46 views
1

我有一個文件LIST,它具有每行字符序列。每行標有一個類別,即「C」。例如:在未知數量的收藏中編寫嵌套doseq

C: w r t y i o p s d f g h j k l z b n m 
V: a e i o u 
E: n m ng 

我想用doseq打印C,V和E(或者只是C和V,C和E等)的各種組合,但一般我不知道會不會嵌套集合在編譯時。

I.e.

"CV" [x y] (str x y) 
"CVE" [x y z] (str x y z) 
"CVCV" [x y z a] (str x y z a) 

我的代碼word-generator.clj

(ns word-generator) 
(use 'clojure.string) 
(import 'java.io.File) 
(use 'clojure.java.io) 

(defn get-lines [fname] 
    (with-open [r (reader fname)] 
    (doall (line-seq r)))) 

(defn get-list [x lines] 
    (first (remove nil? 
    (for [num (range (count lines)) ] 
    (if (= (first(split (nth lines num) #"\s+")) x) 
    (rest(split (nth lines num) #"\s+"))))))) 

(def sounds(get-lines "LIST")) ;; get the list 


(def C (get-list "C:" sounds)) ;; map consonants 
(def V (get-list "V:" sounds)) ;; map vowels 
(def E (get-list "E:" sounds)) ;; map end consonants 
(def LI "CVE") ;; word structure 


(defn word-runner[carry args depth] 
    (doseq [x C y V z E] (println (str x y z)))) ;; iterate and make the words 

(defn runner[] 
    ((print "enter arg list: ") 
    (def INPUT (read-line)) 
    (word-runner "" INPUT 0))) 

我如何能實現word-runner使doseq確實在文件中找到的字符的所有序列嵌套循環 - 但是沒有在知道文件中的行數編譯時?

+0

「word-runner」函數的'carry'參數代表什麼? – tnoda

+0

它的工作像這樣用C '函數(攜帶ARGS深度) 如果(參數[深度] == args.length) 打印進位+字符 別的 功能(進行ARGS深度+ 1) ' 攜帶簡單地是用來建立一個字符串,但在clojure中看到有更聰明的方法來做事情。 – zeitue

+1

您可以在Clojure中省略「carry」和「depth」。 '跑步者'可以像'(定義跑步者[標籤] ...)'。那麼你期望'word-runner'函數能夠返回。例如,'(word-runner [「CV」「CVE」])'應該返回一個映射或向量的向量? – tnoda

回答

2

這實際上是一個組合問題,沒有太多的循環。使用math.combinatorics庫中的cartesian-product函數來解決您的問題。

;; alternative implementation of "word-runner" 
(defn print-cartesian-products [& seqs] 
    (doseq [combs (apply cartesian-product seqs)] 
     (println (apply str combs)))) 
+0

使用此代碼導致以下輸出,我無法弄清楚如何使它工作 '(「w」「r」「t 「y」「i」「o」「p」「s」「d」「f」「g」「h」「j」「k」「l」「z」「b」「n」「m」) (「a」「e」「i」「o」「u」) 零 ' – zeitue

+1

你是什麼意思「如何使它工作?」在我看來,你需要修改你的程序。而不是移植C代碼,您需要了解更多Clojure基礎知識。 – noahlz

+0

感謝您的信息,我應該在哪裏看? – zeitue