Ошибка стекирования потока при использовании факториала рекурсией на ктолине

Это мой код. Это дает ошибку переполнения стека 30 раз на выходной консоли

fun main(args:Array<String>){ var no:Int=Integer.parseInt(readLine())//read input from user and convert to Integer var ans:Int=calculateFact(no) //call function and store to ans variable println("Factorial of "+no+" is "+ans) //print result } fun calculateFact(no:Int):Int //function for recursion { if(no==0) { return 1 } return (no*calculateFact(no)) } 

Я не знаю, что такое ошибка.

    Вы должны вернуться

     no*calculateFact(no - 1) 

    не

     no*calculateFact(no) 

    иначе рекурсия никогда не закончится.

    Помимо ошибки в рекурсии, которая уже была указана, стоит упомянуть, что ваш метод будет работать только правильно для чисел до 12 , начиная с 13! больше максимального значения, которое вы можете сохранить в Int . Поэтому для чисел 13 и выше вы получите «случайные» результаты из-за переполнения.

    Если вы просто используете BigInteger вместо этого, он будет работать до тех пор, пока стек вызовов не станет слишком глубоким и не вызовет переполнение стека, это произойдет около 8000 на моей машине.

     fun calculateFact(no: BigInteger): BigInteger { if (no == BigInteger.ZERO) { return BigInteger.ONE } return (no * calculateFact(no - BigInteger.ONE)) } fun main(args: Array<String>) { val no: BigInteger = BigInteger(readLine()) val ans: BigInteger = calculateFact(no) println("Factorial of $no is $ans") } 

    Если вы хотите обрабатывать числа, превышающие это, вы можете использовать функцию tailrec (это конкретное решение взято из этой статьи):

     tailrec fun calculateFact(acc: BigInteger, n: BigInteger): BigInteger { if (n == BigInteger.ZERO) { return acc } return calculateFact(n * acc, n - BigInteger.ONE) } fun calculateFact(n: BigInteger) : BigInteger { return calculateFact(BigInteger.ONE, n) } fun main(args: Array<String>) { val n: BigInteger = BigInteger(readLine()) val ans: BigInteger = calculateFact(n) println("Factorial of $n is $ans") } 

    Это будет работать для чисел до нескольких сотен тысяч, ваша проблема с этим станет временем, затрачиваемым на выполнение вместо ограничений памяти.

      fun main(args:Array<String>) { var no:Int = Integer.parseInt(readLine()) //read input from user and convert to Integer var ans:Int=calculateFact(no) //call function and store to ans variable println("Factorial of "+no+" is "+ans) //print result } fun calculateFact(no:Int):Int { //function for recursion if(no==0) { return 1 } return (no*calculateFact(no - 1)) // you forgot to decrease the no here. } 

    Если вы didnot уменьшить нет, то он будет вызывать метод calculateFact() все время. Проверьте код, он будет работать.