2

「縮小マップ」機能を実装しようとしています。つまり、fの最初の 2 つの項目に適用した結果と、そのcoll結果に適用fした結果、および の 3 番目の項目collなどで構成されるシーケンスを返す必要があります。

(def c [[0 0 0 0] [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]])

(defn- sum-vector [v1 v2]
  (map + v1 v2))

(defn reduce-map [f coll & acc]
  (if (< (count coll) 2)
    (if (empty? acc) coll acc)
    (let [head (apply f (take 2 coll))
          tail (drop 2 coll)]
      (recur f (conj tail head) (conj acc head)))))

たとえば、この関数を次のように呼び出します。

(reduce-map sum-vector c)

返す必要があります:

[[1 0 0 0] [1 1 0 0] [1 1 1 0] [1 1 1 1]]

(実際には、おそらく最初の項目も変更されずに返され、より適切に模倣されるはずmapですが、後で修正できます。)

さて、これはそれが返すものです:

((1 1 1 1) (1 1 1 0) (1 1 0 0) (1 0 0 0))

(ny) seq の最後に「プッシュ」するにはどうすればよいですか?

を代入reduce-mapするとrecur、次のように返されます。

(((1 1 1 1) ((1 1 1 0) ((1 1 0 0) ((1 0 0 0))))))

recur上記のコードの真の再帰との違いは何ですか?

そして、組み込みの、またはより優れた、またはより慣用的な実装方法はありますreduce-mapか?

最後に、出力シーケンスを遅延させたいと思います。全体を でラップするだけlazy-seqですか?

4

1 に答える 1

10

これは のように聞こえますreductions

seq の最後での「プッシュ」について: 一般に、seq には「終了」がありません。(iterate inc 0).

リストの最後での「プッシュ」について: リストはそのように設計されていません。ベクトルを使用します。アキュムレータに[]ではなくをシードしますnil

についてlazy-seq: の代わりに「真の」再帰を使用しますrecur。ここに例があります:

(defn integer-seq
  [start]
  (lazy-seq
    (cons start (integer-seq (inc start)))))
于 2010-11-23T09:57:55.037 に答える