P11 - 改进的游程编码

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

P11 - 改进的游程编码

Modified run-length encoding

官方模块: Problems.P11 核心函数: encodeModified


← P10 游程编码 | P12 解码游程编码 →


题目描述

修改 P10 的 encode 函数——如果元素没有重复,直接以 Single 形式放入结果列表;只有重复的元素才编码为 Multiple n x

输出类型不再是 [(Int, a)],而是自定义的 Encoding a 类型。

Encoding 数据类型

1data Encoding a
2  = Single a           -- 只出现一次的元素
3  | Multiple Int a     -- 出现 n 次的元素
4  deriving (Show, Eq)

函数签名

1encodeModified :: Eq a => [a] -> [Encoding a]

思路

基于 P09 的 pack(或 P10 的 encode),对每一组连续重复元素:

实现

方法一:基于 pack

1import Data.List (group)
2
3encodeModified :: Eq a => [a] -> [Encoding a]
4encodeModified = map encodeGroup . group
5  where
6    encodeGroup [x] = Single x
7    encodeGroup xs  = Multiple (length xs) (head xs)

group 把连续重复元素打包成子列表,然后根据子列表长度选择 SingleMultiple

方法二:基于 P10 的 encode

1encodeModified :: Eq a => [a] -> [Encoding a]
2encodeModified = map convert . encode
3  where
4    convert (1, x) = Single x
5    convert (n, x) = Multiple n x

先做 P10 的标准编码,再把 (1, x) 转为 Single x

方法三:手动递归

1encodeModified :: Eq a => [a] -> [Encoding a]
2encodeModified [] = []
3encodeModified (x:xs) = case span (== x) xs of
4  (same, rest) -> let n = 1 + length same
5                  in (if n == 1 then Single x else Multiple n x) : encodeModified rest

span (== x) xs 切分出与 x 相等的连续段,根据长度直接构造 Encoding

测试

1>>> encodeModified "aaaabccaadeeee"
2[Multiple 4 'a', Single 'b', Multiple 2 'c', Multiple 2 'a', Single 'd', Multiple 4 'e']
3
4>>> encodeModified []
5[]
6
7>>> encodeModified "a"
8[Single 'a']

参考


← P10 游程编码 | P12 解码游程编码 →