运行 序列的长度编码
Run length encoding of sequences
所以我正在尝试解决这个问题,这是我想出的代码:
首先我有一个 pack 函数,接收一个列表并将相同的元素分组到一个向量中。
(defn pack [lst]
(def a [])
(def vect [])
(cond
(empty? lst)
lst
:else
(loop [i 0]
(def r (get lst i))
(def t (get lst (+ i 1)))
(if (= r t)
(def vect (conj vect r))
)
(if (not= r t)
(and (def vect (conj vect r)) (and (def a (conj a vect)) (def vect [])))
)
(if (= i (- (count lst) 1))
a
(recur (inc i))
)
))
)
例如,如果我有这个向量:
(def tes '[a a a a b c c a a d e e e e])
pack 函数将 return 这个:
[[a a a a] [b] [c c] [a a] [d] [e e e e]]
然后我尝试用这段代码完成问题的“编码”部分:
(def v1 [])
(def v2 [])
(conj v2 (conj v1 (count (get (pack tes) 0)) (get (get (pack tes) 0) 0)))
它 return 编辑了我想要的内容,一个向量“v2”和一个包含“编码”项目的向量“v1”。
[[4 a]]
所以现在我尝试实现功能:
(defn encode [lst]
(loop [index 0 limit (count (pack lst)) v1 [] v2[]]
(if (= index limit)
lst
(conj v2 (conj v1 (count (get (pack tes) index)) (get (get (pack tes) index) index)))
)
(recur (inc index) limit v1 v2)
)
)
(encode tes)
但是我得到这个错误:
2021/03/07 00:00:21 got exception from server /usr/local/bin/lein: line 152:
28 Killed "$LEIN_JAVA_CMD" "${BOOTCLASSPATH[@]}" -Dfile.encoding=UTF-8 -Dmaven.wagon.http.ssl.easy=false -Dmaven.wagon.rto=10000 $LEIN_JVM_OPTS
-Dleiningen.original.pwd="$ORIGINAL_PWD" -Dleiningen.script="[=17=]" -classpath "$CLASSPATH" clojure.main -m leiningen.core.main "$@"
2021/03/07 01:42:20 error reading from server EOF
有什么方法可以修复我的代码或更有效地解决问题但仍然 return 一个向量?
这是更有效的解决方案:
(defn pack [lst]
(letfn [(pack-help [lst]
(if (empty? lst) '()
(let [elem (first lst)]
(cons (vec (take-while #(= % elem) lst))
(pack-help (drop-while #(= % elem) lst))))))]
(vec (pack-help lst))))
(defn pack-with-count [lst]
(mapv #(vector (count %) (first %))
(pack lst)))
(defn unpack [packed-lst]
(into [] (apply concat packed-lst)))
(pack '[a a a a b c c a a d e e e e])
(pack-with-count '[a a a a b c c a a d e e e e])
(unpack '[[a a a a] [b] [c c] [a a] [d] [e e e e]])
通常,只要您达到 loop/recur,标准库中的某些部分将允许您使用高阶函数获得所需的效果。您无需实施接线,只需专注于您的意图。
(def tes '[a a a a b c c a a d e e e e])
(partition-by identity tes)
; => ((a a a a) (b) (c c) (a a) (d) (e e e e))
(map (juxt count first) *1)
; => ([4 a] [1 b] [2 c] [2 a] [1 d] [4 e])
(mapcat #(apply repeat %) *1)
; => (a a a a b c c a a d e e e e)
此处 *1 只是“先前结果”的 REPL shorthand - 如果您需要将这些组合成函数,这将替换为您的参数。
如果你真的需要向量而不是每个阶段的外部集合的序列,你可以用 vec 包装(将惰性序列转换为向量),或者使用 mapv 而不是 map。
最后 - 您从 lein 收到的错误消息是语法错误,而不是逻辑或代码问题。如果没有足够的右括号,Clojure 通常会标记意外的 EOF。
(println "because we left them open like this -"
考虑在 IDE 内的 REPL 中工作,或者如果这不可能,则使用适合您的括号的文本编辑器。
juxt
可以用在pack
函数中:
(defn pack [xs]
(map (juxt count first) (partition-by identity xs)))
(defn unpack [xs]
(mapcat #(apply repeat %) xs))
所以我正在尝试解决这个问题,这是我想出的代码:
首先我有一个 pack 函数,接收一个列表并将相同的元素分组到一个向量中。
(defn pack [lst]
(def a [])
(def vect [])
(cond
(empty? lst)
lst
:else
(loop [i 0]
(def r (get lst i))
(def t (get lst (+ i 1)))
(if (= r t)
(def vect (conj vect r))
)
(if (not= r t)
(and (def vect (conj vect r)) (and (def a (conj a vect)) (def vect [])))
)
(if (= i (- (count lst) 1))
a
(recur (inc i))
)
))
)
例如,如果我有这个向量:
(def tes '[a a a a b c c a a d e e e e])
pack 函数将 return 这个:
[[a a a a] [b] [c c] [a a] [d] [e e e e]]
然后我尝试用这段代码完成问题的“编码”部分:
(def v1 [])
(def v2 [])
(conj v2 (conj v1 (count (get (pack tes) 0)) (get (get (pack tes) 0) 0)))
它 return 编辑了我想要的内容,一个向量“v2”和一个包含“编码”项目的向量“v1”。
[[4 a]]
所以现在我尝试实现功能:
(defn encode [lst]
(loop [index 0 limit (count (pack lst)) v1 [] v2[]]
(if (= index limit)
lst
(conj v2 (conj v1 (count (get (pack tes) index)) (get (get (pack tes) index) index)))
)
(recur (inc index) limit v1 v2)
)
)
(encode tes)
但是我得到这个错误:
2021/03/07 00:00:21 got exception from server /usr/local/bin/lein: line 152:
28 Killed "$LEIN_JAVA_CMD" "${BOOTCLASSPATH[@]}" -Dfile.encoding=UTF-8 -Dmaven.wagon.http.ssl.easy=false -Dmaven.wagon.rto=10000 $LEIN_JVM_OPTS
-Dleiningen.original.pwd="$ORIGINAL_PWD" -Dleiningen.script="[=17=]" -classpath "$CLASSPATH" clojure.main -m leiningen.core.main "$@"
2021/03/07 01:42:20 error reading from server EOF
有什么方法可以修复我的代码或更有效地解决问题但仍然 return 一个向量?
这是更有效的解决方案:
(defn pack [lst]
(letfn [(pack-help [lst]
(if (empty? lst) '()
(let [elem (first lst)]
(cons (vec (take-while #(= % elem) lst))
(pack-help (drop-while #(= % elem) lst))))))]
(vec (pack-help lst))))
(defn pack-with-count [lst]
(mapv #(vector (count %) (first %))
(pack lst)))
(defn unpack [packed-lst]
(into [] (apply concat packed-lst)))
(pack '[a a a a b c c a a d e e e e])
(pack-with-count '[a a a a b c c a a d e e e e])
(unpack '[[a a a a] [b] [c c] [a a] [d] [e e e e]])
通常,只要您达到 loop/recur,标准库中的某些部分将允许您使用高阶函数获得所需的效果。您无需实施接线,只需专注于您的意图。
(def tes '[a a a a b c c a a d e e e e])
(partition-by identity tes)
; => ((a a a a) (b) (c c) (a a) (d) (e e e e))
(map (juxt count first) *1)
; => ([4 a] [1 b] [2 c] [2 a] [1 d] [4 e])
(mapcat #(apply repeat %) *1)
; => (a a a a b c c a a d e e e e)
此处 *1 只是“先前结果”的 REPL shorthand - 如果您需要将这些组合成函数,这将替换为您的参数。
如果你真的需要向量而不是每个阶段的外部集合的序列,你可以用 vec 包装(将惰性序列转换为向量),或者使用 mapv 而不是 map。
最后 - 您从 lein 收到的错误消息是语法错误,而不是逻辑或代码问题。如果没有足够的右括号,Clojure 通常会标记意外的 EOF。
(println "because we left them open like this -"
考虑在 IDE 内的 REPL 中工作,或者如果这不可能,则使用适合您的括号的文本编辑器。
juxt
可以用在pack
函数中:
(defn pack [xs]
(map (juxt count first) (partition-by identity xs)))
(defn unpack [xs]
(mapcat #(apply repeat %) xs))