P51 - 纠错码

2026-09-07 00:00    #Haskell   #99题   #逻辑  

P51 - 纠错码

Error correction codes

官方模块:Problems.P51 核心函数:errorCorrectingEncode, errorCorrectingDecode


← P50 霍夫曼编码 | P52 合取范式 →


题目描述

用长度为 3 的重复码编码布尔位:False 变为三个 FalseTrue 同理。解码时对每组三位多数表决,因此每组最多一个错误仍可恢复。

函数签名

1errorCorrectingEncode :: [Bool] -> [Bool]
2errorCorrectingDecode :: [Bool] -> [Bool]

实现

方法一:replicate + 递归解码

 1errorCorrectingEncode :: [Bool] -> [Bool]
 2errorCorrectingEncode = concatMap (replicate 3)
 3
 4errorCorrectingDecode :: [Bool] -> [Bool]
 5errorCorrectingDecode [] = []
 6errorCorrectingDecode xs
 7  | length chunk == 3 = majority chunk : errorCorrectingDecode rest
 8  | otherwise         = error "incomplete repetition-code block"
 9  where
10    (chunk, rest) = splitAt 3 xs
11    majority bits = length (filter id bits) * 2 > length bits

编码使用 concatMap 表达“每个输入位展开成三位”,解码则按三位分组计数。不是完整码字的尾部会被拒绝,避免悄悄生成没有多数票的结果。

方法二:模式匹配 + 多数门

 1errorCorrectingEncode :: [Bool] -> [Bool]
 2errorCorrectingEncode [] = []
 3errorCorrectingEncode (bit:bits) =
 4  bit : bit : bit : errorCorrectingEncode bits
 5
 6errorCorrectingDecode :: [Bool] -> [Bool]
 7errorCorrectingDecode [] = []
 8errorCorrectingDecode (a:b:c:rest) =
 9  vote a b c : errorCorrectingDecode rest
10errorCorrectingDecode _ = error "incomplete repetition-code block"
11
12vote :: Bool -> Bool -> Bool -> Bool
13vote a b c = (a && b) || (a && c) || (b && c)

这个版本直接匹配三个布尔值,用多数门表达式投票,不构造临时分组,也不计算列表长度。

方法对比

方法特点
replicate + splitAt列表组合风格,容易推广到其他重复次数
模式匹配 + 多数门固定三重复码,单次扫描且不构造临时列表

测试

1>>> errorCorrectingEncode [True, False]
2[True,True,True,False,False,False]
3>>> errorCorrectingDecode [True,True,True,False,False,False]
4[True,False]
5-- 模拟单 bit 错误:
6>>> errorCorrectingDecode [False,True,True,True,False,False]
7[True,False]
8>>> errorCorrectingDecode [True,False]
9*** Exception: incomplete repetition-code block

参考