You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell问题:如何获取列表中大于左右邻居的元素列表

解决Haskell提取列表峰值元素的问题

嘿,我来帮你搞定这个问题!你要做的是从Integer列表里找出那些严格大于左右两个邻居的元素(也就是“峰值”),比如输入[0,1,5,2,3,7,8,4]要得到[5,8]对吧?你的代码返回空列表,大概率是没有正确处理“同时查看当前元素和左右邻居”的逻辑,我给你拆解一下正确的实现思路和代码:

核心思路:滑动三元组筛选

要找峰值,我们需要每次同时观察三个连续元素:前一个、当前、后一个。Haskell里可以用zip3函数把原列表、原列表的尾部、原列表尾部的尾部组合起来,这样就能得到一组组(prev, curr, next)的三元组,然后只筛选出curr比prev和next都大的情况,再提取curr即可。

简洁的列表推导式实现

findPeaks :: [Integer] -> [Integer]
findPeaks xs = [ curr | (prev, curr, next) <- zip3 xs (tail xs) (tail $ tail xs), curr > prev, curr > next ]

测试一下:

> findPeaks [0,1,5,2,3,7,8,4]
[5,8]

完全符合你的预期!

递归版本(帮助理解底层逻辑)

如果你想更清楚地理解递归处理的过程,也可以写一个递归实现:

findPeaksRec :: [Integer] -> [Integer]
findPeaksRec [] = []          -- 空列表直接返回空
findPeaksRec [_] = []         -- 单个元素没有邻居,返回空
findPeaksRec [_,_] = []       -- 两个元素也没有完整的左右邻居,返回空
findPeaksRec (a:b:c:rest)
  | b > a && b > c = b : findPeaksRec (b:c:rest)  -- b是峰值,加入结果继续处理后续
  | otherwise = findPeaksRec (b:c:rest)           -- 不是峰值,继续向后遍历

你可能踩的坑

  • 边界条件处理错误:如果你的代码没有考虑列表长度小于3的情况,可能会触发错误或者返回空;
  • 三元组组合错误:比如没有正确用zip3把三个偏移后的列表组合,导致拿到的邻居元素不对;
  • 过滤条件写反:比如把curr > prev写成了prev > curr,自然筛选不到任何元素。

内容的提问来源于stack exchange,提问作者dziulis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:31:41