scheme中表只能操作头部带来的一个问题

很多简单的算法,为了能够转成尾递归,不得不采取比较繁琐的计算过程,或者使用多遍的遍历过程。在scheme中,比如map的实现,按照定义的实现

(define (map p l)

  (if (null? l)

       '()

      (cons (p (car l)) (map p (cdr l)))))

是一个普通的递归,无法转成迭代进行计算。为了使用迭代的结构,必须首先定义一个list的反转过程,其定义为

(define (reverse l)

    (define (reverse-iter r l)

          (if (null? l)

              r

              (reverse-iter (cons (car l) r) (cdr l))))

    (reverse-iter '() l))

然后才能定义迭代的map

(define (map p l)

 (define (map-reverse-iter r p l)

    (if (null? l)

        r

        (map-reverse-iter (cons (p (car l)) r) p (cdr l))))

  (reverse (map-reverse-iter '() p l)))

这里的实现原理是先用map-reverse-iter将p作用到每个元素中去,然后使用逆序存储,所以需要使用reverse来将顺序翻转过来。如果使用C/C++之类的循环结构,实现起来非常简单而且直观。就其原因来说,我以为出现的情况是因为cons这个操作限制住了lisp的操作,遍历必须是从前往后遍历,而链表则从久表使用头部插入得到。而map操作最合适的是从头到尾部遍历,在尾部插入。因此实现起来不是很直观。类似的操作还有filter,这个操作需要跟map同样的访问模式,迭代的实现也是必须先从前往后遍历,结果是头插入,然后将结果逆序。

(define (filter p l)

  (define (filter-iter s p l)

    (if (null? l)

        s

        (if (p (car l))

            (filter-iter (cons (car l) s) p (cdr l))

            (filter-iter s p (cdr l))

        )))

  (reverse (filter-iter '() p l)))

转载于:https://www.cnblogs.com/mathlover/archive/2012/09/29/2708968.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值