Scala自定义encode方法返回空Vector的原因排查
问题分析:为什么你的Scala函数返回空Vector?
你的代码返回空Vector主要有两个核心问题:递归终止条件缺失,以及for推导式的逻辑完全不符合你想要的前缀生成需求。
1. 递归终止条件缺失
当递归调用encode(ws.drop(split))到最后,ws.drop(split)会变成空列表Nil。此时你的函数里的for推导式:
for { split <- (1 to ws.length) // 当ws是Nil时,ws.length=0,(1 to 0)是空范围 wst <- ws.take(split) wdt <- encode(ws.drop(split)) } yield wst::wdt
循环范围1 to 0是空的,所以整个for推导式没有产生任何元素,返回空Vector。这个空结果会向上传递,导致所有上层递归的wdt <- encode(...)都没有元素可取,最终整个函数返回空。
2. for推导式的逻辑错误
你的目标是生成输入列表的所有前缀(take(1), take(2), take(3)),但你的代码逻辑完全偏离了这个需求:
wst <- ws.take(split):这是在遍历ws.take(split)中的每个元素,而不是把ws.take(split)整个作为一个列表元素。比如当split=1时,你得到的是单个元素('a',2),而不是列表List(('a',2))。- 递归调用
encode(ws.drop(split))并将wst和wdt拼接,这是在尝试生成元素的组合(类似笛卡尔积),而不是生成前缀序列。
修正后的实现
如果你需要生成输入列表的所有前缀序列,最简单的实现不需要递归,直接利用map遍历长度范围即可:
val ws: List[(Char, Int)] = List(('a',2), ('e',1), ('t',1)) def encode(ws: List[(Char, Int)]): Seq[List[(Char, Int)]] = (1 to ws.length).map(ws.take)
执行这个函数会返回你期望的结果:
Vector(List(('a',2)), List(('a',2), ('e',1)), List(('a',2), ('e',1), ('t',1)))
如果想用递归实现(比如练习递归逻辑),可以这样写:
def encode(ws: List[(Char, Int)]): Seq[List[(Char, Int)]] = ws match { case Nil => Seq.empty // 终止条件:空列表返回空序列 case _ => val shorterPrefixes = encode(ws.init) // 先获取去掉最后一个元素的所有前缀 shorterPrefixes :+ ws // 加上当前完整列表作为最长前缀 }
内容的提问来源于stack exchange,提问作者Aavik
相关产品推荐
相关产品推荐

