2017-09-04 19 views
0

私はBigIntegerの階乗をしたい(Kotlinで)。 テール再帰で、私が9000を実行しようとするとStackOverFlowエラーが発生します!。 非再帰的な関数を使って私はそれを行うことができます...しかし、私はこの種のエラーを避ける方法は非常に不思議です。ここでJava/Kotlin/IntelliJ IDEAでStackOverFlowエラーを回避する方法は?

は私のコードです:

import java.math.BigInteger 

fun tail_recursion_factorial(n: BigInteger, factorialOfN: BigInteger = BigInteger.valueOf(2)): BigInteger { 
    return when(n){ 
     BigInteger.ONE -> BigInteger.ONE 
     BigInteger.valueOf(2) -> factorialOfN 
     else -> tail_recursion_factorial(n.minus(BigInteger.ONE), n.times(factorialOfN)) 
    } 
} 
fun non_recursive_factorial(n: BigInteger): BigInteger{ 
    var i: BigInteger = BigInteger.ONE 
    var factorial: BigInteger = BigInteger.ONE 
    while (i<=n){ 
     factorial = factorial.times(i) 
     i = i.plus(BigInteger.ONE) 
    } 
    return factorial 
} 
fun main(args: Array<String>){ 
    print("n == ") 
    var n = readLine()!! 
    //recursive 
    //println("$n! is ${tail_recursion_factorial(BigInteger(n))}") 
    //non-recursive 
    println("$n! is ${non_recursive_factorial(BigInteger(n))}") 
} 
+0

[Javaスタックサイズを大きくする方法](https://stackoverflow.com/questions/3700459/how-to-increase-the-java-stack-size) – konsolas

答えて

4

これは、JVMは、末尾再帰を最適化していないため、言語レベルで解決しなければならない問題です。

幸いにも、Kotlin言語はtailrecという修飾語を提供しているため、funの代わりにtailrec funと書くことができます。コンパイラは、tailrec関数内のテールコールをループに変換します。ループは、発生しているスタックオーバーフローを取り除きます。

+0

詳細情報:https:///kotlinlang.org/docs/reference/functions.html#tail-recursive-functions –

関連する問題