2017-07-02 51 views
2

我想編寫一個在矢量中的現有元素之間插入元素的函數。插入的元素是前後元素的函數,第一個元素和最後一個元素不受影響。如何創建一個函數在矢量中的每對元素之間插入一個元素

E.g.我想插入的元素是該先於和後於它的元素的平均值:

輸入:

[1 10 15]

輸出:

[1 5.5 10 12.5 15]

什麼是最好的方法這在Clojure中?我可以解決這個問題

回答

4

這裏的另一種方式:

(defn insert-mean-between [xs] 
    (let [f (fn [x y] 
      [(* (+ x y) 0.5) y])] 
    (->> xs 
     (partition 2 1) 
     (mapcat (partial apply f)) 
     (cons (first xs)) 
     vec))) 

(insert-mean-between [1 10 15]) 
;;=> [1 5.5 10 12.5 15] 

主要伎倆f正在返回答案和RHS輸入。這種方式後來他們將組合在一起而不重複。你將遇到的唯一問題是第一個元素缺失。所以我們只是把它放在前面。從一開始我們必須知道cons當我們選擇返回RHS而不是LHS時是一個方便的操作。

作爲計算平均只是一個例子,一種改進的解決方案將是爲插入到獨立的平均值的/不管功能:

(defn calc-mean [x y] (* (+ x y) 0.5) 
(insert-between calc-mean [1 10 15]) 

然後,更一般的插入功能可以是:

(defn insert-between [g xs] 
    (->> xs 
     (partition 2 1) 
     (mapcat (fn [[x y]] [(g x y) y])) 
     (cons (first xs)))) 
+0

如果只有'分區'具有完整的換能器變體(arity妨礙了我的設想),這可以成爲如何使用換能器的絕佳示例。 – Thumbnail

0

的一種方法是模式匹配Vectorf s t,我假定它有3個元素

然後,創建變量分配第一值first + second/2和第二中值second + third /2

最後用你想要的組合返回一個新的Vector

例,(我使用雷音REPL

user=> (defn insert_medians[vect] 
    #_=> (let [[f s t] vect 
    #_=>  m1 (float (/ (+ f s) 2)) 
    #_=>  m2 (float (/ (+ s t) 2))] 
    #_=>  [f m1 s m2 t])) 
#'user/insert_medians 

user=> (insert_medians [1 10 15]) 
[1 5.5 10 12.5 15] 

如果向量大於3個elems的,你需要先找到所有的中位數,然後插入使用interleave FN原來的矢量。

+0

不幸的是,矢量的長度不一致。一些矢量具有> 1000個元素 – Mehul

4

,沒有遞歸懶惰序列生成變異的名單將是不完整:

(defn with-avg [[x1 & [x2 :as tail] :as items]] 
    (when (seq items) 
    (if (seq tail) 
     (lazy-cat [x1 (/ (+ x1 x2) 2)] (with-avg tail)) 
     [x1]))) 

user> (with-avg [1 2 3 4 5]) 
;;=> (1 3/2 2 5/2 3 7/2 4 9/2 5) 
user> (with-avg [1]) 
;;=> [1] 
user> (with-avg []) 
;;=> nil 
user> (with-avg [1 2]) 
;;=> (1 3/2 2) 
user> (with-avg [1 2 3]) 
;;=>(1 3/2 2 5/2 3) 
+2

嵌套解構的很好例子。 – Thumbnail

0
(defn insert-between 
    "Inserts elements between existing elements in a vector v. The inserted 
    elements are a result of applying the function f to the elements that precede 
    and succeed it, with the first and last elements of v remaining unaffected." 
    [f [x & xs :as v]] 
    (->> (partition 2 1 v) 
     (mapcat (fn [[a b]] [(f a b) b])) 
     (cons x) 
     (into []))) 

(defn mean [& numbers] 
    (float (/ (apply + numbers) (count numbers)))) 

(insert-between mean [1 10 15]) ; => [1 5.5 10 10 12.5 15] 
(insert-between + [1 10 15 20 25]) ; => [1 11 10 25 15 35 20 45 25] 
(insert-between mean [])   ; => [nil] :(
相關問題