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

摘要:
根据定义的实现(define(mappl)(if(null)),必须首先定义一个列表反转过程,因此需要使用反转来反转顺序。我认为发生这种情况的原因是cons操作限制了lisp的操作,而链表是通过使用头插入从长表中获得的。map操作最适合从头到尾遍历,此操作需要与map相同的访问模式。

很多简单的算法,为了能够转成尾递归,不得不采取比较繁琐的计算过程,或者使用多遍的遍历过程。在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)))

免责声明:文章转载自《scheme中表只能操作头部带来的一个问题》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇chromedriver的使用selenium自动化测试工具的使用总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

算法笔试:返回第一个不重复的字符变种,不区分大小写

题目 给定一个字符串,返回字符串中第一个不重复的字符,比如aBAd返回B,AbabcfA返回c,判断时不区分给定字符大小写,但返回时需要返回原本大小写(其实就是通过索引返回即可)。 思路 1、暴力破解 使用双重循环,声明一个变量保存字符出现的次数, 第二层循环中与第一层当前循环字符比较,如果相同字符出现次数++, 如果第二层循环遍历完以后字符出现次数为1,...

java8 的files、path类相关文件遍历API

Path的两种初始化(应该还有别的方式) Path file = new File(path).toPath(); Paths.get 判断是文件、是目录 Files.isRegularFile(file) Files.isDirectory(file) javadoc说,还有既不是文件也不是目录的情况 Files.find 通过属性和路径筛选,可以筛选是...

[读码时间] for循环遍历设置所有DIV块元素背景色为红色

说明:代码取自网络,注释为笔者学习时根据自己的理解所添加 又及:原作者采用了匈牙利变量命名法,如变量为对象,则前缀字母 o,表示为 object。 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>for循环...

java alibaba fastJson 遍历数组json

import java.util.*; import com.alibaba.fastjson.*; public class Test { public static void main(String[] args) { //方法1 String json = "[{"companyId":"111111111","com...

Map遍历法则

    /** * 如果既要遍历key又要value,那么建议这种方式,应为如果先获取keySet然后再执行map.get(key),map内部会执行两次遍历。 * 一次是在获取keySet的时候,一次是在遍历所有key的时候。 */ // 当我调用put(key,value)方法的时候...

ucos(八)软件定时器

一、概述   内核提供了一个模拟定时器的机制,类似于任务,但是占用资源少,只能做一些简单的定时控制,如可以定时的喂狗、控灯。在软件定时器,不能添加时间管理函数、阻塞等待函数(等待互斥锁/信号量/事件标志组/消息队列)。 1.创建软件定时器 void OSTmrCreate (OS_TMR *p_tmr, CPU_CHAR *p_name, OS_TIC...