【问题标题】:What am I doing wrong while translating a Scala Recursion function into a Tail-Recursion function?将 Scala 递归函数转换为尾递归函数时我做错了什么?
【发布时间】:2020-01-31 03:51:25
【问题描述】:

我正在尝试使用这个工作递归函数(下)...

    def cubeIt(n: Int): Int = {
        println("acc:"+acc);
        println("n: "+n);
        if(n==0){
            return 0;
        }
        else if(n>0){
            return cubeIt(n-1) + 3*(n*n) - 3*n + 1
        }
        else{
            return cubeIt(n+1) - 3*(n*n) - 3*n - 1
        }
    }

...把它变成一个尾递归函数。

import scala.annotation.tailrec

@tailrec
def cubeItHelper(n: Int, acc: Int): Int = { /* Implement cubeIt as a tail recursion */
    if(n==0){
        return acc;
    }
    if(n>0){
        return cubeItHelper(n-1, acc+(3*(n*n) - 3*n + 1));
    }
    else{
        return cubeItHelper(n+1, (acc+((-3)*(n*n) - 3*n - 1)));

    }
}
/*- 
This is the main function that the users will use. 
It should call the helper with the correct initial value of acc argument. 
Just replace the ??? with the correct initial value for the acc argument.
-*/
def cubeItTail(n: Int): Int = {
    if(n==0){
        return 0;
    }
    else{
        cubeItHelper(n, 0);
    }
}

使用上面的代码,它会输出:

acc:0
n: 5
acc:61
n: 4
acc:98
n: 3
acc:117
n: 2
acc:124
n: 1
......

前四个测试行正确完成

n: -100
acc:-29701
n: -99
acc:-58808
n: -98
acc:-87327
...(goes forever)

这些是测试语句(它挂在最后一个):

assert(cubeItTail(5) == 125)
assert(cubeItTail(-5) == -125)
assert(cubeItTail(-3) == -27)
assert(cubeItTail(0) == 0)
assert( (-100 to 100).forall( x => (cubeItTail(x) == x * x * x)), "Test Passed!")

如果有人能告诉我我在这里做错了什么,我将不胜感激。

【问题讨论】:

  • 您删除的指纹是问题的根本原因吗?如果是这样,您应该将它们保留在问题中/
  • 好吧我更新它
  • 这里提问有两个方面,一是得到答案,二是把这个答案留给以后有同样问题的人找到,不用再问

标签: scala recursion tail-recursion tail


【解决方案1】:

打印语句

println("acc:"+acc); println("n: "+n);

在帮助函数中导致 Jupyter Notebook 崩溃。但是,它们可能完全在不同的环境中运行。请注意会有很多打印语句。

【讨论】:

    【解决方案2】:

    cubeItTail 的参数可能为负数,在这种情况下,您需要将 -1 传递给 cubeItHelper

    def cubeItTail(n: Int): Int = {
        if (n == 0) {
            return 0;
        }
        else if (n > 0) {
            cubeItHelper(n, 1);
        }
        else {
            cubeItHelper(n, -1);
        }
    }
    

    【讨论】:

    • 这已经在辅助函数的 if 语句中说明了。我更新了帖子以解释我得到的一个新的无限循环
    • 它对我来说似乎终止了,虽然它确实递归了好几次
    • 它是否像“测试通过!”一样终止?还是它引发了超时错误?也许对我来说 jupyter notebook 无法处理?
    • 有可能,我认为 Jupyter 可能有奇怪的线程可能会干扰。我认为“测试通过了!”当断言失败时打印,以便我们知道哪个断言失败。但是我可以看到(-100 to 100).forall( x => (cubeItTail(x) == x * x * x))true,所以你的函数确实有效。
    • 谢谢!实际上,我只是在没有 cmets 的情况下运行它并且它正确完成了。
    猜你喜欢
    • 2016-01-06
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多