获取字符串的所有移动k大小的分区

时间:2013-11-13 20:57:18

标签: clojure

我正试图让所有“移动”分区大小为k的字符串。基本上,我想沿着字符串移动一个大小为k的窗口并获得该k字。

这是一个例子,

k :3

输入:ABDEFGH

输出:ABD,EFG,BDE,FGH,DEF

我的想法是沿着输入走,放下一个头和分区,然后从先前(现在无头)的序列再次掉头,但我不确定该怎么做...而且,也许有这样做的更好方法是什么?以下是我的想法。

(#(partition k input) (collection of s where head was consecutively dropped))

3 个答案:

答案 0 :(得分:7)

Clojure中的字符串可以视为字符序列,因此您可以直接对它们进行分区。要获取一系列重叠分区,请使用接受大小和步骤的版本:

user> (partition 3 1 "abcdef")
((\a \b \c) (\b \c \d) (\c \d \e) (\d \e \f))

要将字符序列放回字符串,只需将str应用于它:

user> (apply str '(\a \b \c))
"abc"

把它们放在一起:

user> (map (partial apply str) (partition 3 1 "abcdef"))
("abc" "bcd" "cde" "def")

答案 1 :(得分:2)

以下是字符串partitionpartition-all的实现,返回lazy-seq字符串,使用subs进行拆分。如果你需要高性能的字符串转换,那么创建字符串转换的速度要快得多(平均快8倍,参见下面的标准基准),而不是创建char-seqs。

(defn partition-string
  "Like partition, but splits string using subs and returns a
   lazy-seq of strings."
  ([n s]
     (partition-string n n s))
  ([n p s]
     (lazy-seq
      (if-not (< (count s) n)
        (cons
         (subs s 0 n)
         (->> (subs s p)
              (partition-string n p)))))))

(defn partition-string-all
  "Like partition-all, but splits string using subs and returns a
   lazy-seq of strings."
  ([n s]
     (partition-string-all n n s))
  ([n p s]
     (let [less (if (< (count s) n)
                  (count s))]
       (lazy-seq
        (cons
         (subs s 0 (or less n))
         (if-not less
           (->> (subs s p)
                (partition-string-all n p))))))))

;; Alex answer:
;; (let [test-str "abcdefghijklmnopqrstuwxyz"]
;;   (criterium.core/bench
;;    (doall
;;     (map (partial apply str) (partition 3 1 test-str)))))
;; WARNING: Final GC required 1.010207840526515 % of runtime
;; Evaluation count : 773220 in 60 samples of 12887 calls.
;; Execution time mean : 79.900801 µs
;; Execution time std-deviation : 2.008823 µs
;; Execution time lower quantile : 77.725304 µs ( 2.5%)
;; Execution time upper quantile : 83.888349 µs (97.5%)
;; Overhead used : 17.786101 ns

;; Found 3 outliers in 60 samples (5.0000 %)
;; low-severe    3 (5.0000 %)
;; Variance from outliers : 12.5585 % Variance is moderately inflated by outliers

;; KobbyPemson answer:
;; (let [test-str "abcdefghijklmnopqrstuwxyz"]
;;   (criterium.core/bench
;;    (doall
;;     (moving-partition test-str 3))))
;; WARNING: Final GC required 1.674347646128195 % of runtime
;; Evaluation count : 386820 in 60 samples of 6447 calls.
;; Execution time mean : 161.928479 µs
;; Execution time std-deviation : 8.362590 µs
;; Execution time lower quantile : 154.707888 µs ( 2.5%)
;; Execution time upper quantile : 184.095816 µs (97.5%)
;; Overhead used : 17.786101 ns

;; Found 3 outliers in 60 samples (5.0000 %)
;; low-severe       2 (3.3333 %)
;; low-mild         1 (1.6667 %)
;; Variance from outliers : 36.8985 % Variance is moderately inflated by outliers

;; This answer
;; (let [test-str "abcdefghijklmnopqrstuwxyz"]
;;   (criterium.core/bench
;;    (doall
;;     (partition-string 3 1 test-str))))
;; WARNING: Final GC required 1.317098148979236 % of runtime
;; Evaluation count : 5706000 in 60 samples of 95100 calls.
;; Execution time mean : 10.480174 µs
;; Execution time std-deviation : 240.957206 ns
;; Execution time lower quantile : 10.234580 µs ( 2.5%)
;; Execution time upper quantile : 11.075740 µs (97.5%)
;; Overhead used : 17.786101 ns

;; Found 3 outliers in 60 samples (5.0000 %)
;; low-severe    3 (5.0000 %)
;; Variance from outliers : 10.9961 % Variance is moderately inflated by outliers

答案 2 :(得分:0)

(defn moving-partition 
    [input k] 
    (map #(.substring input % (+ k %)) 
        (range (- (count input) (dec k)))))