P10 (*) 列表的游程编码

问题描述

使用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))))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值