Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 如何在分隔符上拆分向量_Clojure - Fatal编程技术网

Clojure 如何在分隔符上拆分向量

Clojure 如何在分隔符上拆分向量,clojure,Clojure,我有一个包含数字的向量。 向量的结构如下所示: 任意长度的项目 项目之间的分隔符[0 0](0重复5次) 我想编写一个函数split,用于检索项目列表(不带分隔符):它类似于 例如: (split [123 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 199]) ; => [[123 0 1] [1 1] [1 0 1] [0 0 1 199]] 备注:该代码必须有效,因为向量的长度约为100万。 感谢您的帮助。这里有一种方法--使

我有一个包含数字的向量。 向量的结构如下所示:

  • 任意长度的项目
  • 项目之间的分隔符[0 0](0重复5次)
  • 我想编写一个函数
    split
    ,用于检索项目列表(不带分隔符):它类似于

    例如:

    (split [123 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 199])
    ; => [[123 0 1] [1 1] [1 0 1] [0 0 1 199]]
    
    备注:该代码必须有效,因为向量的长度约为100万。

    感谢您的帮助。

    这里有一种方法--使用硬连线的
    [0]
    分隔符,但很容易概括:

    (defn split5z [xs]
      (let [delim [0 0 0 0 0]
            step (fn step [xs seg]
                   (lazy-seq
                    (if-let [xs (seq xs)]
                      (let [window (take 5 xs)]
                        (if (= window delim)
                          (cons seg (step (drop 5 xs) []))
                          (step (rest xs) (conj seg (first xs)))))
                      (list seg))))]
        (step xs [])))
    
    将其应用于示例输入:

    (split5z [123 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 199])
    ;= ([123 0 1] [1 1] [1 0 1] [1 199])
    
    如果希望输出为向量而不是一系列向量,请使用
    vec

    另一种方法——这段时间急切地使用
    循环
    /
    重复

    (defn split5z [sep xs]
      (let [scnt (count sep)]
        (loop [xs  (seq xs)
               out []
               seg []]
          (if xs
            (if (= (take scnt xs) sep)
              (recur (nthnext xs scnt)
                     (conj out seg)
                     [])
              (recur (next xs)
                     out
                     (conj seg (first xs))))
            (if (seq seg)
              (conj out seg)
              seg)))))
    
    在REPL上:

    (split5z [0 0 0 0 0]
             [123 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 199])
    ;= [[123 0 1] [1 1] [1 0 1] [1 199]]
    
    在这里:

    懒惰的解决方案:

    (defn split [v]
      (let [delim (repeat 5 0)
            i (->> v (partition 5 1) (take-while #(not= delim %)) count)]
        (if (zero? i) [v] (lazy-seq (cons (subvec v 0 i)
                                          (split (subvec v (+ i 5))))))))
    
    比如说

    (split [123 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 199])
    ; ([123 0 1] [1 1] [1 0 1] [0 0 1 199])
    

    很好,但是如果
    0
    启动或结束有效的数据块:
    (拆分[01 0 0 0 0 2]);=>((01 0 0 0 2))
    。然而,语法对于
    ((01)(02))
    ((0110)(2))
    是否正确是不明确的。@A.韦伯完全正确。如果有6个或更多的零对齐,分隔符应该是前5个零还是最后5个零?也许问题的作者有一个线索。…。@a.Webb不仅语法模棱两可,而且据我所知,它并没有对所有可能的项目列表进行编码:例如,我无法设计出解码为
    [[1 0][0 1]]
    的向量。我已经向OP询问了这个问题。@A.Webb我需要与相同的行为。项目列表:
    [[1 0][0 1]]
    可行吗?分裂成它的向量是什么?@Thumbnail我需要与相同的行为。
    (split [123 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 199])
    ; ([123 0 1] [1 1] [1 0 1] [0 0 1 199])