P02 - 取列表倒数第二个元素

2026-09-07 00:00    #Haskell   #99题   #列表  

P02 - 取列表倒数第二个元素

Penultimate element of a list

官方模块: Problems.P02 核心函数: myButLast


← P01 取列表最后一个元素 | P03 取列表第 k 个元素 →



← P01 取列表最后一个元素 | P03 取列表第 k 个元素 →


题目描述

找出列表的倒数第二个元素(penultimate element)。如果列表不足两个元素,返回 Nothing

函数签名

1myButLast :: [a] -> Maybe a

思路

和 P01 类似,但需要多一个元素的前瞻。模式匹配时有三种情况:

实现

方法一:标准递归

1myButLast :: [a] -> Maybe a
2myButLast []       = Nothing
3myButLast [_]      = Nothing
4myButLast [x, _]   = Just x
5myButLast (_:xs)   = myButLast xs

前两个模式处理不足两元素的 case;[x, _] 匹配正好两个元素,返回第一个;(_:xs) 丢弃头部,在更短的列表上继续找。

方法二:利用 reverselistToMaybe

1import Data.Maybe (listToMaybe)
2
3myButLast :: [a] -> Maybe a
4myButLast [] = Nothing
5myButLast xs = listToMaybe . drop 1 . reverse $ xs

reverse 反转后倒数第二个变成正数第二个,drop 1 扔掉第一个,再取 listToMaybe

方法三:使用标准库 init + last

1myButLast :: [a] -> Maybe a
2myButLast [] = Nothing
3myButLast [_] = Nothing
4myButLast xs = Just . last . init $ xs

init 去掉最后一个元素,last 取结果列表的最后一个(即原列表的倒数第二个)。

测试

 1>>> myButLast [1,2,3,4]
 2Just 3
 3
 4>>> myButLast ['a'..'z']
 5Just 'y'
 6
 7>>> myButLast ['a']
 8Nothing
 9
10>>> myButLast []
11Nothing

参考


← P01 取列表最后一个元素 | P03 取列表第 k 个元素 →