递归求和函数,我如何限制总和?

Posted

技术标签:

【中文标题】递归求和函数,我如何限制总和?【英文标题】:Recursive sum function, How do i limit the sum? 【发布时间】:2021-12-19 12:10:40 【问题描述】:

我们的目标是将这个总和编码成一个递归函数。 Sum

到目前为止,我已经尝试过这样编写代码。

def under(u: Int): Int = 
    var i1 = u/2
    var i = i1+1
    if (  u/2 == 1 ) then u + 1 - 2 * 1
    else   (u + 1 - 2 * i) + under(u-1)

似乎我遇到了递归部分的问题,但我无法弄清楚出了什么问题。 理论上,under(5) 应该产生 10。

【问题讨论】:

如果您只是想评估您链接的图像中的公式,您应该相应地制定问题。截至目前,问题与选择的答案不匹配。 【参考方案1】:

你的逻辑是错误的。它应该从i=1i=n/2 进行迭代(无论是通过循环、递归还是集合都无关紧要)。但按原样使用n 和当前i

(1 to (n/2)).map(i => n + 1 - 2 * i).sum

您(或多或少)运行从i=1i=n(或者更确切地说是n 到1)的计算,但是您使用i/2 而不是n 而不是i,而是使用i/2+1 . (从 i=1 到 i=n 的 (n/2 + 1 - 2 * i) 的总和)。

// actually what you do is more like (1 to n).toList.reverse
// rather than (1 to n)
(1 to n).map(i => i/2 + 1 - 2 * (i/2 + 1)).sum

这是一个不同的公式。它有两倍的元素要求和,每个元素的一部分都在变化而不是保持不变,而另一部分的值错误。

要使用递归实现相同的逻辑,您必须执行以下操作:

// as one function with default args

// tail recursive version
def under(n: Int, i: Int = 1, sum: Int = 0): Int =
  if (i > n/2) sum
  else under(n, i+1, sum + (n + 2 - 2 * i))

// not tail recursive
def under(n: Int, i: Int = 1): Int =
  if (i > n/2) 0
  else (n + 2 - 2 * i) + under(n, i + 1)

// with nested functions without default args

def under(n: Int): Int = 
  // tail recursive
  def helper(i: Int, sum: Int): Int =
    if (i > n/2) sum
    else helper(i + 1, sum + (n + 2 - 2 * i))
  helper(1, 0)


def under(n: Int): Int = 
  // not tail recursive
  def helper(i: Int): Int =
    if (i > n/2) 0
    else (n + 2 - 2 * i) + helper(i + 1)
  helper(1)

【讨论】:

【参考方案2】:

附带说明:根本不需要使用任何迭代/递归。这是一个明确的公式:

def g(n: Int) = n / 2 * (n - n / 2)

结果与

相同
def h(n: Int) = (1 to n / 2).map(i => n + 1 - 2 * i).sum

n 为奇数的情况下,两者都假设您希望对n / 2 进行下限,即上述两个函数的行为与

def j(n: Int) = (math.ceil(n / 2.0) * math.floor(n / 2.0)).toInt

(至少在出现舍入错误之前)。

【讨论】:

以上是关于递归求和函数,我如何限制总和?的主要内容,如果未能解决你的问题,请参考以下文章

wps表格如何跨表根据月份求金额总和?

为啥我的多线程并行求和函数的向量受限于线程数?

匿名函数和闭包规避xdebug限制的函数递归深度限制

如何使用递归函数计算和打印以下序列的前 N ​​个元素的总和

求和函数没有在熊猫中以正确的方式显示总和[关闭]

使用多个连接和求和函数进行查询,给出错误的总数或总和