F# for循环实现continue逻辑:else分支后继续循环填充列表并返回
F#回文数乘积列表生成问题修复
原代码存在的核心问题
- 不可变绑定问题:F#默认
let绑定的变量是不可变的,你声明的acc = []始终是空列表,(i * j) :: acc只是生成了新列表没有更新到原变量,最终返回结果必然为空 - 循环体无副作用:F#的
for循环体要求返回unit类型,你写在if/else分支的列表值会被直接丢弃,既不会更新累加器也不会影响循环执行 - 回文判断冗余:原回文判断需要手动处理字符串分片,对奇数长度的数字兼容性有隐患,可以简化实现
修复方案
方案1:惯用函数式写法(推荐)
不需要手动维护累加器和循环,直接用F#的序列表达式完成过滤、生成逻辑,写法简洁无可变状态:
// 简化后的回文判断函数,自动兼容奇偶长度数字 let isPoli num = let s = string num s = (s |> Seq.rev |> Seq.toArray |> System.String) let biggestPoliProduct (range: int list) = seq { for i in range do for j in range do let product = i * j if isPoli product then yield product } |> Seq.toList // 调用测试 biggestPoliProduct [ 1 .. 100 ]
方案2:贴合原写法逻辑的可变累加器版本
如果你需要沿用你原有的循环+累加器的写法思路,可以用可变集合实现:
let isPoli num = let s = string num s = (s |> Seq.rev |> Seq.toArray |> System.String) let biggestPoliProduct (range: int list) = // 用可变的ResizeArray做累加 let acc = ResizeArray<int>() for i in range do for j in range do let product = i * j if isPoli product then acc.Add(product) // 转成F#原生列表返回 acc |> List.ofSeq biggestPoliProduct [ 1 .. 100 ]
补充说明
两种方案都会完整遍历所有乘积组合,else分支不需要写任何逻辑就能自动继续执行循环,完成所有回文数乘积的收集后返回最终列表。如果需要获取最大的回文乘积,只需要在返回的列表上调用List.max方法即可。
内容的提问来源于stack exchange,提问作者kakakakakakakk
相关产品推荐
相关产品推荐

