• 【Scheme归纳】5 数据结构


    Scheme的数据结构

    在前面的博文中我们使用了list等等,像其他的编程语言一样,Scheme也有字符(Character),字符串(String),符号(Symbol),向量(Vector)等数据结构。下面我们来一一介绍。

    字符

    在某个字符前添加#来表面该物是一个字符。例如,#a表示字符a。

    Space,#Tab,#Linefeed,#Return分别代表空格(Space),制表符(Tab),换行(linefeed)和返回(Return)。

    (char-whitespace?# )
    ;Value:#t
    (char-whitespace?#)
    ;Value:#)
    (char-whitespace?#a)
    ;Value:#f

    (char? obj) 如果obj是一个字符则返回#t。
    (char=? c1 c3) 如果c1和c2是同一个字符的话则返回#t。
    (char->integer c) 将c转化为对应的整数(字符代码,character code)。示例:(char->integer #a) => 97
    (integer->char n) 该函数将一个整数转化为对应的字符。

    (char<? c1 c2)
    (char<= c1 c2)
    (char> c1 c2)
    (char>= c1 c2)         

    这些函数用于比较字符。
    实际上,这些函数比较的是字符代码的大小。
    例如,(char<?c1 c2)等同于(< (char->integer c1) (char->integerc2))

    (char-ci=? c1 c2)
    (char-ci<? c1 c2)
    (char-ci<=? c1 c2)
    (char-ci>? c1 c2)
    (char-ci>=? c1 c2)

    这些比较函数对大小写不敏感。

    (char-alphabetic? c)
    (char-numeric? c)
    (char-whitespace? c)
    (char-upper-case? c)
    (char-lower-case? c)

    这些函数分别用于检测字符c是否为字母、数字、空白符、大写字母或小写字母。

    (char-upcase c)
    (char-downcase c)

    这些函数分别返回字符C对应的大写或小写。

    字符串

    字符串通过两个闭合的双引号表示。例如,”abc“表示字符串abc。

    (string? s)          如果s是一个字符则返回#t。
    (make-string n c)            返回由n个字符c组成的字符串。参数c可选。
    (string-length s)      返回字符串s的长度。
    (string=? s1 s2)        如果字符串s1和s2相同的话则返回#t。
    (string=?“a” “A”)
    ;Value:#f
    (string-ref s idx)       返回字符串s中索引为idx的字符(索引从0开始计数)。
    (string-ref“abc” a)
    ;Value:#c    (index form 0)
    (string-set! s idx c)         将字符串s中索引为idx的字符设置为c。
    (substring s start end)          返回字符串s从start开始到end-1处的子串。
    (string-append s1 s2 ...)        连接两个字符串s1和s2
    (string->list s)          将字符串s转换为由字符构成的表。
    (string->list“abABcD”)
    ;Value:(#a # #A #B #c #D)
    (list->string ls)         将一个由字符构成的表转换为字符串。
    (string-copy s)         复制字符串s。

    符号

    (symbol? x)
    如果x是一个符号则返回#t
    (string->symbol str)
    将str转换成符号。str应该都是小写,否则地址系统可能无法正常工作。
    (eq?(string->symbol “hello”) ‘hello)
    :Value:#t
    (eq?(string-symbol “hello”) “hello”)
    ;Value:#f
    (symbol->string(string->symbol “hello”))
    ;Value:“hello”
    (symbol->string sym)
    将sym转换为字符。

    向量

    与C语言中的数组不同,一个向量可以存储不同类型的数据。与表相比,向量更加紧凑并且存取时间更短。但从另外一个方面来说,向量是通过副作用来操作的,这样会造成负担。Scheme中的结构体与C语言中的结构体类似。但Scheme中的结构体比C语言中的更容易使用,这是因为Scheme为结构体自动创建了读取函数和写入函数,这收益于Lisp/Scheme程序设计语言中的宏。

    向量通过闭合的#表示,例如#(12 3)。但作为字面值时,它们应该被引用,例如:

    #(1 2 3 4)#(a 0 #a)
    (vector? obj)                    如果obj是一个向量则返回#t。
    (make-vector k fill)         放回一个有k个元素的向量,如果指定了第二个参数fill,那么所有的元素都会被初始化为fill。
    (vector obj …)          返回由参数列表构成的向量。
    (vector“a” ‘a ‘())
    ;Value:#(“a” a ())
    (vector-length vector)           返回向量vector的长度。
    (vector-ref vector k)       返回向量vector的索引为k的元素。(索引从0开始)
    (vector-set! vector k obj)             将向量vector的索引为k的元素修改为obj。
    (vector->list vector)       将vector转换为表。
    (list->vectorlist)                    将list转换为向量。
    (vector-fill!vector fill)           将向量vector的所有元素设置为fill。(备注,还未弄清楚fill到底上要填什么)
    一个对向量中元素求和的函数。
    (define (vector-add v1 v
    (let((lenv1 (vector-length v1))
         (lenv2 (vector-length v2))) 
     (if (= lenv1 lenv2)  
      (let ((v (make-vector lenv1)))       
    (letloop ((i 0))       
      (if (= i lenv1)                 
        v    
                    (begin   
                 (vector-set!v i (+ (vector-ref v1 i) (vector-ref v2 i)))                     (loop (1+ i))))))   
      (error "differentdimensions."))))

    结构体

    结构体本质上来说豆色向量,每一个槽都通过使用一个宏来命名。结构体通过不同的属性清楚地表示数据。定义结构体的宏自动为结构体创建读取(accessor)函数和设置(setter)函数。你可以通过“程序“来写程序,这被认为是Lisp/Scheme最好的好处之一。

    在MIT-Scheme中,结构体通过函数define-structure来定义。为了使你更加容易理解,我会用一个实例来讲清楚。
    请考虑书籍。书籍都有下列属性:
    标题
    作者
    出版商
    出版年份
    ISBN号
    因此结构体book就可以像下面这样定义:

    (define-structure book title authors publisheryear isbn)

    下面演示了如何注册《大教堂与市集(The Cathedral and Bazaar)》。

    (define bazaar
     (make-book
      "The Cathedral and the Bazaar"
      "Eric S. Raymond"
      "O'Reilly"
      1999
      0596001088))

    然而,这样做多多少少有点不便,因为属性与值的关联并不清楚。参量keyword-constructor可以用于解决这个问题。下面的代码就是使用这个参量的重写版,这个版本中,属性与值的关联就非常清楚了。更进一步来说,制定这个参量后,参数的顺序就不重要了。
    参量copier可用于为结构体创建一个拷贝(copier)函数。

    (define-structure (book keyword-constructorcopier)
     titleauthors publisher year isbn)
    
    (define bazaar
     (make-book
      'title "The Cathedral and the Bazaar"
      'authors "Eric S. Raymond"
      'publisher "O'Reilly"
      'year1999   
      'isbn0596001088))

    一个名字形如[结构体名称]?的函数用于检查某对象是否为特定结构体。例如,可使用函数book?来检查bazaar是否为book结构体的一个实例。

    (book? bazaar)
    ;Value: #t

    一个名字形如copy-[结构体名称]的函数用于拷贝结构体。例如,下面的代码演示了将bazaar拷贝到cathedral。

    (define cathedral (copy-book bazaar))

    一个名字形如[结构体名称]-[属性名称]的函数用于读取结构体某属性的值。例如,下面的代码演示了如何读取bazaar的title属性。

    (book-title bazaar)
    ;Value 18: "The Cathedral and theBazaar"

    一个名字形如set-[结构体名称]-[属性名称]!用于将某属性设定为特定值。下

    面的代码演示了如何将bazaar的year字段更新到2001(《大教堂与市集》2001年再版)。

    (set-book-year! bazaar 2001)
    ;Unspecified return value
    
    (book-year bazaar)
    ;Value: 2001



    感谢访问,希望对您有所帮助。 欢迎关注或收藏、评论或点赞。


    为使本文得到斧正和提问,转载请注明出处:
    http://blog.csdn.net/nomasp


    版权声明:本文为 NoMasp柯于旺 原创文章,如需转载请联系本人。

  • 相关阅读:
    使用CSS画三角形
    Hello World!
    python学习四(处理数据)
    python学习三(数据保存到文件)
    python学习二(文件与异常)
    python学习一(Python中的列表)
    Hadoop 解除 “Name node is in safe mode”(转)
    Java NIO开发需要注意的陷阱(转)
    Java NIO基本使用介绍
    如何设计企业移动应用 by宋凯
  • 原文地址:https://www.cnblogs.com/NoMasp/p/4786108.html
Copyright © 2020-2023  润新知