Elixir子集和问题代码无输出,请求排查终止条件等错误
子集和问题代码错误排查与修正
代码中的核心错误
- 未定义变量:
sum_of_one函数里调用sumofone时用了l,这是未定义的变量,应替换成数组长度length(arr_of_digits) - 变量不可变特性误用:
[k | v]仅生成新列表,但未将其传递给后续递归调用,原v变量不会被修改,导致选中元素从未加入路径 - 终止条件逻辑缺陷:
if(sum==0)分支返回的有效子集未被收集,且条件不满足时该if会返回nil,污染递归结果n==0时直接返回v,但此时若sum不为0,该返回值无效,应返回空列表而非当前路径
- 递归结果未处理:两个递归分支(不选当前元素、选当前元素)的返回值均被丢弃,未合并返回,导致最终无输出结果
- 语法错误:代码末尾的分号多余,Elixir无需分号结束语句
修正后的代码
defmodule Todos do # 查找所有和为sum_val的子集 def sum_of_one(arr_of_digits, sum_val) do sumofone(arr_of_digits, length(arr_of_digits), [], sum_val) end defp sumofone(_arr, 0, _current_path, 0) do # 数组遍历完且和为0,返回当前路径的列表(统一格式) [[]] end defp sumofone(_arr, 0, _current_path, _sum) do # 数组遍历完但和不为0,返回空列表表示无有效子集 [] end defp sumofone(arr, n, current_path, sum) do current_element = Enum.at(arr, n - 1) # 不选当前元素的分支 without_current = sumofone(arr, n - 1, current_path, sum) # 选当前元素的分支,仅当当前元素不大于剩余sum时执行 with_current = if current_element <= sum do new_path = [current_element | current_path] sumofone(arr, n - 1, new_path, sum - current_element) else [] end # 合并两个分支的结果 without_current ++ with_current end end
说明
- 使用私有函数
sumofone(加defp)避免外部直接调用 - 拆分终止条件为两个子句,逻辑更清晰,避免
if带来的nil问题 - 正确处理变量不可变特性,将新生成的路径传递给递归调用
- 合并两个递归分支的结果,确保所有有效子集都被收集
- 添加判断:当前元素大于剩余sum时跳过选元素分支,减少无效递归
内容的提问来源于stack exchange,提问作者Jadu
相关产品推荐
相关产品推荐

