zoukankan      html  css  js  c++  java
  • 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)))

  • 相关阅读:
    Kubernetes 无法删除pod实例的排查过程
    kubeadm 生成的token过期后,集群增加节点
    linux 常规操作EOF写法梳理
    linux下EOF写法梳理
    容器云之弹性伸缩
    QEMU,KVM及QEMU-KVM介绍
    听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构
    代码内存泄露检测(1) MLeaksFinder (Wechat开源) + FBRetainCycleDetector (FaceBook开源)
    Xcode 创建使用多个 target (1)
    iOS 多线程的简单理解(4) 线程锁的简单使用
  • 原文地址:https://www.cnblogs.com/mathlover/p/2708968.html
Copyright © 2011-2022 走看看