P10 (*) 列表的游程编码

来源:互联网 发布:淘宝官方营销中心 编辑:程序博客网 时间:2024/06/02 08:24

问题描述

使用P09的结论来实现所谓的游程编码,这是一种数据压缩的方法。连续重复的元素会编码成(N E)形式的列表,其中N为元素E重复的次数。如

sash> (encode '(a a a a b c c a a d e e e e))sash> ((4 a) (1 b) (2 c) (2 a) (1 d) (4 e))

解法

P09已经提供了将相同元素打包成子列表的函数,我们只需提供将子列表转换成(N E)形式的函数即可,剩下的就是简单的列表递归。

  • 递归实现

    (define encode(lambda (ls)   (let ([p (pack ls)]      [enc (lambda (sub)             (list              (length sub)              (car sub)))])  (let f ([p p])    (cond      [(null? p) '()]      [else (cons             (enc (car p))             (f (cdr p)))]))))) 

    这里用let绑定了一个局部的函数,因为该函数只在一个地方被使用。

  • reduce实现

    (define encode(lambda (ls)   (let ([p (pack ls)]      [enc (lambda (sub)             (list              (length sub)              (car sub)))])  (fold-right   (lambda (e a)     (cons      (enc e)      a))   '()   p))))
  • map实现

    相比reduce,实际上这个更适合用map实现,因为原列表和结果链表的元素的关系是一一对应的。

(define encode  (lambda (ls)    (let ([p (pack ls)]          [enc (lambda (sub)                 (list                  (length sub)                  (car sub)))])      (map       (lambda (e)         (enc e))       p))))
0 0
原创粉丝点击