添加一个Vector的元素,而不使用`reduce`或`apply` [英] Adding the elements of a Vector without using `reduce` or `apply`

查看:151
本文介绍了添加一个Vector的元素,而不使用`reduce`或`apply`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图重新实现 reduce 方法,所以它可以添加一些数字,通常可以使用 reduce ,如:

 (reduce + [1 2 3]);; 6 
(newRd + [1 2 3]);; 6

所以我想也许可以使用递归函数来添加向量的第一个元素每次它被调用,并再次为其余的矢量。像这样:

 (defn newRd [list] 
(let [sum 0]
(不是0(计数列表))
(+ sum(第一列表))
(newRd(rest list))


)$ b b

我想我没有正确地进行本地存储。任何建议或者更好的方法?

解决方案

您的代码中有两个错误:



1)您不将当前的和添加到递归调用结果



2)当列表为空时应返回0

更正的变体:

 (defn newRd [list] 
($($)
(如果(不是= 0(计数列表))
(+ sum(first list)
(newRd(rest list)))
sum ))

in repl:

  user> (newRd [1 2 3 4])
10

bit:



首先你不需要 let 语句中的总和,因为 sum always = 0



其次,有一个lib函数 empty?检查列表是否为空。

 (defn newRd [list] 
(if- b $ b(+(first list)
(newRd(rest list)))
0))

但是请记住:clojure不会执行尾调用优化,所以很容易导致堆栈owerflow有一个长列表:

  user> (newRd(repeat 1000000 1))
StackOverflowError user / newRd(form-init289434844644272272.clj:73)


$ b b

所以最好使用loop / recur

 (defn sum-list [list] 
[list list sum 0]
(if(empty?list)
sum
(recur(rest list)(+ sum(first list))))))



in repl:

 用户> (sum-list(repeat 1000000 1))
1000000

函数本身的尾递归:

 (defn newRd [list sum] 
(if-
(recur(rest list)(+ sum(first list)))
sum))

user> (newRd(repeat 1000000 1)0)
1000000

,以便不在每次调用中传递第二个参数:

 (defn newRd 
0))
([list sum]
(if-not(empty?list)
(recur(rest list)(+ sum(first list)))
sum) ))


So I am trying to re-implement the reduce method, so it can add a couple of numbers that normally can be done using reduce, like:

(reduce + [1 2 3]) ;; 6
(newRd + [1 2 3])  ;; 6

So I thought maybe it can be done using a recursive function that adds the first element of the vector every time it is called and do it again for the rest of the vector. Something like this:

(defn newRd [list]
  (let [sum 0]
    (if (not= 0 (count list))
      (+ sum (first list))
      (newRd (rest list))
      )
    )
  )

I think I am not doing local storing correctly. Any suggestion or maybe a better approach?

解决方案

there are two mistakes here in your code:

1) you don't add your current sum to the recursive call result

2) you should return zero when the list is empty

corrected variant:

(defn newRd [list]
  (let [sum 0]
    (if (not= 0 (count list))
      (+ sum (first list)
         (newRd (rest list)))
      sum)))

in repl:

user> (newRd [1 2 3 4])
10

next, you can update it a bit:

first you don't really need the sum in let statement, since the sum always = 0

second, there is a lib function empty? to check if list is empty.

(defn newRd [list]
  (if-not (empty? list)
    (+ (first list)
       (newRd (rest list)))
    0))

but remember: clojure doesnt'do tail call optimization, so it is easy to cause stack owerflow with a long list:

user> (newRd (repeat 1000000 1))
StackOverflowError   user/newRd (form-init289434844644272272.clj:73)

so it's preferable to use loop/recur

(defn sum-list [list]
  (loop [list list sum 0]
    (if (empty? list)
      sum
      (recur (rest list) (+ sum (first list))))))

in repl:

user> (sum-list (repeat 1000000 1))
1000000

the other option is to make the function itself tail recursive:

(defn newRd [list sum]
  (if-not (empty? list)
    (recur (rest list) (+ sum (first list)))
    sum))

user> (newRd (repeat 1000000 1) 0)
1000000

then you can add the additoinal arity, for not to pass the second parameter in every call:

(defn newRd
  ([list] (newRd list 0))
  ([list sum]
   (if-not (empty? list)
     (recur (rest list) (+ sum (first list)))
     sum)))

这篇关于添加一个Vector的元素,而不使用`reduce`或`apply`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆