我使用docjure ,它需要为它选择-列功能的列映射。 我想抓住我的所有列,而不必手动指定。 如何生成以下作为一个懒惰的无限向量序列[:A:B:C:d:电子...:AA:AB:AC ....:ZZ ...:XFD]?
Answer 1:
你的问题可以归结为:“ 我如何将数字转换成基26串字母AZ?”。
下面是做到这一点的一种方式 - 可能不是最简洁的方式,而是使之更优雅就留给读者自己练习:)。
假设数字0-25地图 'A' - 'Z',26名映射到 'AA',等等。 首先,我们定义一个函数to-col
,一个整数转换成一列关键字。 您可以使用该功能来生成一个无限序列。
(defn to-col [num]
(loop [n num s ()]
(if (> n 25)
(let [r (mod n 26)]
(recur (dec (/ (- n r) 26)) (cons (char (+ 65 r)) s)))
(keyword (apply str (cons (char (+ 65 n)) s))))))
这就给了你一个方法来生成列关键字的无限序列:
(take 100 (map to-col (range)))
;; => (:A :B :C :D :E :F :G :H :I :J :K :L :M :N :O :P :Q :R :S :T :U :V :W
;; :X :Y :Z :AA :AB :AC :AD :AE :AF :AG :AH :AI :AJ :AK :AL :AM :AN :AO :AP
;; :AQ :AR :AS :AT :AU :AV :AW :AX :AY :AZ :BA :BB :BC :BD :BE :BF :BG :BH
;; :BI :BJ :BK :BL :BM :BN :BO :BP :BQ :BR :BS :BT :BU :BV :BW :BX :BY :BZ
;; :CA :CB :CC :CD :CE :CF :CG :CH :CI :CJ :CK :CL :CM :CN :CO :CP :CQ :CR
;; :CS :CT :CU :CV)
Answer 2:
对于corecursion基本Clojure的函数(“绑结”也差不多了,不是吗?)是迭代:
(def abc (map (comp str char) (range 65 91)))
(defn cols [seed]
(let [next #(for [x %] (for [y seed] (str x y)))]
(->> (iterate #(apply concat (next %)) seed)
(mapcat identity))))
(time (first (drop 475254 (cols abc))))
"Elapsed time: 356.879148 msecs"
"AAAAA"
(doc iterate)
-------------------------
clojure.core/iterate
([f x])
Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects
编辑:该功能的泛化返回“订购”一集的子集
(defn ordered-combinations [seed]
(->> (map list seed)
(iterate #(for [x % y seed] (concat x [y])))
(mapcat identity)))
(def cols
(let [abc (map char (range 65 91))]
(map #(apply str %) (ordered-combinations abc))))
user> (take 30 (map #(apply str %) cols))
("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "AA" "AB" "AC" "AD")
user> (take 28 (ordered-combinations [0 1]))
((0) (1) (0 0) (0 1) (1 0) (1 1) (0 0 0) (0 0 1) (0 1 0) (0 1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1) (0 0 0 0) (0 0 0 1) (0 0 1 0) (0 0 1 1) (0 1 0 0) (0 1 0 1) (0 1 1 0) (0 1 1 1) (1 0 0 0) (1 0 0 1) (1 0 1 0) (1 0 1 1) (1 1 0 0) (1 1 0 1))
Answer 3:
这个答案是错误的; 希望在教育方式。
数学上你所要求的是字母表中的无限序列的所有子集的懒惰序列 。
(take 40 (map #(keyword (apply str %))
(rest (combinatorics/subsets "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))))
(:A :B :C :D :E :F :G :H :I :J :K :L :M :N
:O :P :Q :R :S :T :U :V :W :X :Y :Z :AB :AC
:AD :AE :AF :AG :AH :AI :AJ :AK :AL :AM :AN :AO)
foo.core> (nth (map #(keyword (apply str %))
(rest (combinatorics/subsets "ABCDEFGHIJKLMNOPQRSTUVWXYZ")))
40000)
:BLOUZ
project.clj:
(defproject foo "1.0.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.3.0"]
[ org.clojure/math.combinatorics "0.0.3"]]
:dev-dependencies [[swank-clojure/swank-clojure "1.4.0"]]) ; swank)
使用math.combanatorics:
(ns foo.core
(:require [clojure.math.combinatorics :as combinatorics]))
Answer 4:
正如jneira迭代提到感觉就像做的正确方法。
下面是对他的功能的改善,应该是更清楚的理解,因为它涉及较少的中间类型。 它不像有些根据各地循环/易复发的其他解决方案完全懒:
(defn column-names-seq [alphabet]
(->> (map str alphabet)
(iterate (fn [chars]
(for [x chars
y alphabet]
(str x y))))
(apply concat)))
要使用它,只需要提供一个字母列如:
(take 30 (column-names-seq "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) ;; => ("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "AA" "AB" "AC" "AD")
Answer 5:
我想这可能是你要找的那种东西(如果不是,好吧,至少它是什么,我认为“正确”的答案应该是O)。
(defn stream [seed]
(defn helper [slow]
(concat (map #(str (first slow) %) seed) (lazy-seq (helper (rest slow)))))
(declare delayed)
(let [slow (cons "" (lazy-seq delayed))]
(def delayed (helper slow))
delayed))
(take 25 (stream ["a" "b" "c"]))
("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac" "aba" "abb" "abc" "aca" "acb" "acc" "baa" "bab" "bac" "bba")
代码的git 。 我怀疑我虐待def
可怕,但它的作品。
这个想法是很简单的:我从序列输出并反馈自身。 对于在输出每个值(其也是输入),我生成通过附加各字母的种子序列的新的输出。 由于这是圆形的,它只是不断去(有一个初始的“”,这是在输入,而不是输出,有助于避免产生无中生有)。
供给输出到输入的过程被称为在Haskell的一个相当著名的论文“绑结”。 但它很难用Clojure做的,因为它是一个渴望语言(甚至懒惰序列不是“懒足够”) -我能找到的唯一解决办法是用那些乱七八糟的def
(我怀疑有人可能会做的更好delay
和force
,但我没有运气)。
也许它甚至可以被写成地图吗?
[更新2012-07-19与更紧凑的代码]
在回答相关问题有更好的代码没有(显式的,丑陋的)突变循环引用:绑结Clojure中? (这是相同的思路jneira的答案)。
为了完整起见,这里使用的最终版本iterate
:
(defn stream [seed]
(defn helper [slow] (mapcat (fn [c] (map #(str c %) seed)) slow))
(apply concat (iterate helper seed)))
Answer 6:
有可能是一个办法删除了“”重复,但这里的东西,对我的作品:
(def all-letters (map char (range 65 90)))
(defn kw [& args] (keyword (apply str args)))
(concat
(for [l all-letters] (kw l))
(for [l all-letters l2 all-letters] (kw l l2))
(for [l all-letters l2 all-letters l3 all-letters] (kw l l2 l3)))
Answer 7:
#include<stdio.h>
int main()
{
int n=703;
char arr[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
while(n){
printf("%c ",arr[(n)%26]);
n=(n)/26;
}
return 0;
}
人是如此简单,因为这还是我失去了一些东西....当然上面的程序打印所需的atring相反,我们能够避免使用递归或将其存储在一个字符串扭转这种局面?