码迷,mamicode.com
首页 > 其他好文 > 详细

【Scheme归纳】5 数据结构

时间:2015-02-05 13:17:07      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

Scheme的数据结构

 

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

 

1、字符

 

在某个字符前添加#\来表面该物是一个字符。例如,#\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->integer c2))

 

(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对应的大写或小写。

 

2、字符串

 

字符串通过两个闭合的双引号表示。例如,”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 #\b #\A #\B #\c #\D)

 

(list->string ls)          将一个由字符构成的表转换为字符串。

(string-copy s)          复制字符串s。

 

3、符号

(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转换为字符。

4、向量

 

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

 

向量通过闭合的#表示,例如#(1 2 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->vector list)                     将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)))       

(let loop ((i 0))        

   (if (= i lenv1)                 

     v    

                 (begin   

              (vector-set! v i (+ (vector-ref v1 i) (vector-ref v2 i)))                       (loop (1+ i))))))   

   (error "different dimensions."))))

 

5、结构体

 

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

 

MIT-Scheme中,结构体通过函数define-structure来定义。为了使你更加容易理解,我会用一个实例来讲清楚。

请考虑书籍。书籍都有下列属性:

标题

作者

出版商

出版年份

ISBN号

因此结构体book就可以像下面这样定义:

 

(define-structure book title authors publisher year 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-constructor copier)

  title authors publisher year isbn)

 

(define bazaar

  (make-book

   ‘title "The Cathedral and the Bazaar"

   ‘authors "Eric S. Raymond"

   ‘publisher "O‘Reilly"

   ‘year 1999   

   ‘isbn 0596001088))

 

一个名字形如[结构体名称]?的函数用于检查某对象是否为特定结构体。例如,可使用函数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 the Bazaar"

 

一个名字形如set-[结构体名称]-[属性名称]!用于将某属性设定为特定值。下面的代码演示了如何将bazaar的year字段更新到2001(《大教堂与市集》2001年再版)。

 

(set-book-year! bazaar 2001)

;Unspecified return value

 

(book-year bazaar)

;Value: 2001

【Scheme归纳】5 数据结构

标签:

原文地址:http://www.cnblogs.com/NoMasp/p/4274303.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!