《Chez Scheme初探》定義變量、遞歸、測試性能、並列代碼編寫

簡介:html

Chez Scheme與DrRacket相似,都是Scheme語言家族,其編程總體思路跟傳統語言有很大區別。其語言結構主要採用遞歸的形式,順序執行語句內容須要使用begin關鍵詞。使用define語句來定義變量和函數,使用let語句來綁定某個變量的值並規定做用域,使用time來統計語句運行的時間。java

; 註釋形式,使用分號

; 四則運算
(+ 1 2)   ; 3
(- 5 1)   ; 4
(* 4 3)   ; 12
(/ 4 2)   ; 2

; 條件判斷
(= 2 3)   ; #f

; 變量定義
(define a 3)

; 變量賦值
(set! a 6)

字符串以及symbol(不可變字符串,帶'號的字母)node

; 建立字符串
"awefawef"
; 定義字符串
(define a "awefawef")
; 使字符串中全部字符變爲大寫
(string-upcase "awefawef")

; 建立symbol(不可變的字符串)
'awefawef
; 定義symbol
(define a 'awefawef)

相互轉換:
(symbol->string 'Apple)    ;"Apple"
(string->symbol "Apple")   ;'Apple

函數定義以及操做python

; 定義函數
(define (func1 x) (string-upcase x))
; 使用函數
(func1 "awer")
; 在map中使用函數
(map func1 a)

list數據結構(相似java的ArrayList),是一種鏈表結構。但跟傳統的arraylist不一樣,它的append方法不改變原來的變量,只返回修改後的listapache

; 建立list數據結構
(list "red" "green" "blue")
; 定義list數據結構變量
(define a (list "red" "green" "blue"))
; 查看list長度
(length (list 1 2 3 4))
; 取出list中第2個元素
(list-ref (list 'a 'b 'c) 2)  ; 結果爲'c


; 遍歷list(使用map函數)
(map (lambda (x) (string-upcase x)) (list "red" "green" "blue"))


; 取元素相關操做
(car (list 1 2 3))  ; 取第一個元素,結果爲1
(cdr (list 1 2 4))  ; 取第二個及之後元素,結果爲(2 4)

; 改元素相關操做:
; Don’t confuse cons and append. The cons function takes an element and a list, 
; while append takes a list and a list. That difference is reflected in their types:
(cons 1 '(2 3))             ; 元素和表一塊兒合併成一個新表,並返回
(append '(1 2) '(3 4))      ; 表和表一塊兒合併成一個新表,並返回

vector數據結構(相似Java的數組),與list的區別詳解(6.6.10 Vectors編程

; 建立vector
(vector 'a 'b)  ; 輸出結果爲#(a b)
(define v1 (vector 'a 'b))
; 取出vector第0個元素
(vector-ref v1 0)  ; a
; 修改第0個元素
(vector-set! v1 0 'c)

; 相互轉換
(vector->list vec)
(list->vector lst)

操做哈希表數組

> (define a make-hash-table)  ; 注意區別,不在make-hash-table兩旁加括號的話,系統會認爲你是把這個函數賦值給a,而不是把函數的執行結果賦值給a
> a
#<procedure make-hash-table>
> (define ht (make-hash-table))
> ht
#<eq hashtable>
; 往表中添加(或修改)元素
(put-hash-table! ht 'b "wtf")  ; 注意感嘆號別漏了
; 使用key獲取對應元素,該實例是獲取'b這個key對應的元素,而最後一個參量是指獲取失敗的時候返回的默認值。
(get-hash-table ht 'b #f)
; 獲取key的vector(返回值是一個vector類型,長得像這樣#(a b c))
(hashtable-keys ht)
; 獲取value的vector(返回值是一個vector類型,長得像這樣#(a b c))
(hashtable-values ht)

普通fib函數bash

(define (fact n) (if (= n 1) 1
                             (* n (fact (- n 1))  )
                 )
)

尾遞歸fib函數數據結構

(define (fact-tail n) (fact-rec n n))
(define (fact-rec n p) (if (= n 1) p
                                   (let ( (m (- n 1)) ) 
                                        (fact-rec m (* p m))
                                   )
                       )
)

性能測試app

(let ([a 120000]) (begin (time (begin (fact a) (+ 30 3) )) (time (begin (fact-tail a) (+ 30 3) ))))

測試結果:

(time (begin (fact a) ...))
    115 collections
    11.843750000s elapsed cpu time, including 0.031250000s collecting
    11.867882300s elapsed real time, including 0.040223800s collecting
    13241981264 bytes allocated, including 13012956832 bytes reclaimed
(time (begin (fact-tail a) ...))
    229 collections
    9.796875000s elapsed cpu time, including 0.062500000s collecting
    9.816385400s elapsed real time, including 0.084685200s collecting
    14538387792 bytes allocated, including 14538258416 bytes reclaimed
33

機器:

CPU:i7-8550U  內存24GB

 

後記:

初學scheme類語言會遇到一個比較混淆的東西,就是set!、define、let的區別,以後會進行深刻的探討和講解

輸出結果中帶井號的標識符具體含義

參考racket的數據類型

DATA STRUCTURE   ACCESS       NUMBER     INDICES
List:            sequential   Variable   not used
Struct:          random       Fixed      names
Vector:          random       Fixed      integer
Growable vector: random       Variable   integer
Hash:            random       Variable   hashable
Splay:           random       Variable   non-integer, total order
相關文章
相關標籤/搜索