Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Functional programming 如何在Kotlin中用动态规划实现纯函数?_Functional Programming_Kotlin_Tail Recursion - Fatal编程技术网

Functional programming 如何在Kotlin中用动态规划实现纯函数?

Functional programming 如何在Kotlin中用动态规划实现纯函数?,functional-programming,kotlin,tail-recursion,Functional Programming,Kotlin,Tail Recursion,我一直在尝试将我的一些代码转换为纯函数,以学习如何以函数的方式使用Kotlin,通过这段简单的代码片段,我想不出任何方法使我的CalculateBonaci函数成为纯函数 我知道有一个潜在的递归解决方案,但如果有潜在的堆栈溢出,Kotlin会实现尾部调用优化吗 例如: val fibonacciValues = hashMapOf<Int, BigInteger>(0 to BigInteger.ONE, 1 to BigInteger.ONE); // * TODO

我一直在尝试将我的一些代码转换为纯函数,以学习如何以函数的方式使用Kotlin,通过这段简单的代码片段,我想不出任何方法使我的
CalculateBonaci
函数成为纯函数

我知道有一个潜在的递归解决方案,但如果有潜在的堆栈溢出,Kotlin会实现尾部调用优化吗

例如:

     val fibonacciValues = hashMapOf<Int, BigInteger>(0 to BigInteger.ONE, 1 to BigInteger.ONE);

 // * TODO investigate how to do dynamic programming with a pure function ** //
    private fun calculateFibonacci(n: Int): BigInteger? {
        if (fibonacciValues.contains(n)) {
            return fibonacciValues.get(n)
        } else {
            val f = calculateFibonacci(n - 2)!!.add(calculateFibonacci(n - 1))

            fibonacciValues.put(n, f)
            return f
        }
    }
val fibonacciValues=hashMapOf(0到biginger.ONE,1到biginger.ONE);
//*TODO调查如何使用纯函数进行动态编程**//
私人乐趣计算器(n:Int):BigInteger?{
if(fibonacciValues.contains(n)){
返回fibonacciValues.get(n)
}否则{
val f=calculateFibonacci(n-2)!!。添加(calculateFibonacci(n-1))
fibonacciValues.put(n,f)
返回f
}
}
对于整个片段,我上传了以下要点:

Kotlin是否实现了尾部调用优化


是的,有tailrec这个关键词。

整个事情都是关于打破命令式方法,从顺序操作的角度思考问题

在斐波那契序列的情况下,这可能很棘手,因为很容易将其视为一个整数序列,但如果将其视为一个成对序列,则会变得容易得多

因此,您可以创建一个无限对序列,其中下一对被定义为前一对中的第二个元素和前一对中的元素之和:

generateSequence(1 to 1) { it.second to it.first + it.second }
  .map { it.first }

是的,您可以通过使用
tailrec
关键字标记您的方法来利用尾部调用优化-无需担心堆栈溢出。您只需在
fun
关键字之前应用它:

fun fibonacciAt(n: Int) = {
    tailrec fun fibonacciAcc(n: Int, a: Long, b: Long): Long {
        return when (n == 0) {
            true -> b
            false -> fibonacciAcc(n - 1, a + b, a)
        }
    }

    fibonacciAcc(n, 1, 0)
}
以下是关于国产的更多信息:

fun fib(i: Int): Int {
    tailrec fun go(k: Int, p: Int, c: Int): Int {
        return if (k == 0) p
        else go(k - 1, c, p + c)
    }

    return go(i, 0, 1)
}
实际上显示了一个斐波那契实现作为示例

fun fibonacci(): Sequence<Int> {
    // fibonacci terms
    // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, ...
    return generateSequence(Pair(0, 1), { Pair(it.second, it.first + it.second) }).map { it.first }
}

println(fibonacci().take(10).toList()) // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
fun fibonacci():序列{
//斐波那契项
// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, ...
返回generateSequence(对(0,1),{Pair(it.second,it.first+it.second)}.map{it.first}
}
println(fibonacci().take(10.toList())/[0,1,1,2,3,5,8,13,21,34]

感谢您参考主要文档