列表元素组合对生成问题:代码输出结果不符合预期
解决列表组合对生成的问题
嘿,我明白你的问题啦——你想生成列表里所有不重复的两两组合对,比如给[1,2,3]要得到[(1,2),(1,3),(2,3)],但现在的代码只输出了[(1,2),(2,3)],少了关键的(1,3)对吧?
问题出在哪?
先看看你写的代码:
parings [d] = [] parings (y:ys) = (y, head ys): parings ys
这个逻辑是每次只把当前元素和它紧邻的下一个元素配对,然后递归处理剩下的列表。拿[1,2,3]举例:
- 第一步:取
1和head [2,3]也就是2组成(1,2),然后递归处理[2,3] - 第二步:取
2和head [3]也就是3组成(2,3),然后递归处理[3] - 第三步:触发
parings [d] = []的模式匹配,返回空列表
最后拼接起来就是[(1,2),(2,3)],自然漏掉了1和3的配对。
修正方案
我们需要让当前元素和后续所有元素都生成配对,而不是只和紧邻的那个。这里有两种简洁的实现方式:
方式一:用map和递归拼接
pairings [] = [] pairings (x:xs) = map (\y -> (x, y)) xs ++ pairings xs
- 当列表为空时,返回空列表
- 当列表有头元素
x和尾部xs时:- 用
map把x和xs里的每一个元素都组成配对,得到[(x, y1), (x, y2), ...] - 把这些配对和递归处理
xs得到的配对拼接起来
测试pairings [1,2,3]:
- 用
- 第一步生成
[(1,2),(1,3)],递归处理[2,3]生成[(2,3)] - 拼接后就是
[(1,2),(1,3),(2,3)],完全符合预期!
方式二:用列表推导式(更直观)
如果你导入Data.List里的tails函数,还可以用列表推导式实现:
import Data.List (tails) pairings xs = [(a, b) | (a:rest) <- tails xs, b <- rest]
tails xs会生成xs的所有后缀列表,比如tails [1,2,3]是[[1,2,3],[2,3],[3],[]]- 遍历每个非空后缀
(a:rest),取a和rest里的每个b组成配对,自动覆盖所有不重复的组合对
这两种方式都能完美解决你的问题,选你觉得更易读的就行~
内容的提问来源于stack exchange,提问作者megabowser56
相关产品推荐
相关产品推荐

