Scala中用foldLeft实现阶乘函数出错求助:输入5返回5而非120
问题排查与修复
核心问题
你的代码中(i to 1)生成的是空区间。Scala的to方法默认创建步长为1的区间,当起始值大于结束值时(比如输入5时,i=4,4到1步长1),这个区间没有任何元素。空区间调用foldLeft会直接返回初始值startingInt(也就是5),所以结果不符合预期。
修复方案
方案1:生成有效倒序区间
给to指定负步长,确保区间包含元素:
def computeFactorial(startingInt: Int): Int = { if startingInt == 0 then 1 else { val i = startingInt - 1 (i to 1 by -1).foldLeft(startingInt)(_ * _) } }
4 to 1 by -1会生成4,3,2,1的序列,foldLeft会按照((5*4)*3)*2)*1的逻辑计算,最终得到120。
方案2:更简洁的正序实现
直接用1到目标数的区间结合reduceLeft,更贴合阶乘的定义:
def computeFactorial(startingInt: Int): Int = { if startingInt == 0 then 1 else (1 to startingInt).reduceLeft(_ * _) }
如果想用foldLeft,还可以合并0的情况,同时增加参数校验:
def computeFactorial(startingInt: Int): Int = { require(startingInt >= 0, "阶乘仅支持非负整数") (1 to startingInt).foldLeft(1)(_ * _) }
调试小技巧
如果想查看foldLeft的执行过程,不用依赖断点,可以在函数中加入打印逻辑:
(i to 1).foldLeft(startingInt) { (acc, num) => println(s"当前累计值: $acc, 下一个乘数: $num") acc * num }
运行后会发现没有任何打印输出,证明区间是空的,快速定位问题所在。
内容的提问来源于stack exchange,提问作者Christopher Spears
相关产品推荐
相关产品推荐

