[TOC] ## 技巧 ### 如何设计递归 例子 1 ``` ;由n个 hello构成的表 ;hellos:n->list-of-symbols ;预期值 ;(hellos 0) ;empty ;(hellos 1) ;(cons 'hello empty) ->(cons 'hello (hellos 0)) ;可以看出带有递归性 ; (hellos 2) ; (cons 'hello (cons 'hello empty)) -> (cons 'hello (hellos 1)) (define (hellos n) (cond [(= n 0) empty] [else (cons 'hello (hellos (- n 1)))])) (hellos 2) ;(list 'hello 'hello) ``` 例子 2 ``` ; 阶乘 ; 1!->1 ; 2!->1x2->1x1! ; 3!->1x2x3->3x2! ; n!->nx!(n-1) (define (! n) (cond [(= n 1) 1] [else (* n (! (- n 1))) ])) (! 1);1 (! 3);6 ``` ### 导入自定义文件 hello.rkt ``` #lang racket (provide vhello) ; 声明给外部用 (define vhello "Hello world") (define fhello (lambda () "Hello world")) ``` main.rkt ``` #lang racket (load "hello.rkt") vhello ;"Hello world" ``` 运行 ``` racket mian.rkt ``` ### `[]`与`()` 的区别 * 方括号跟圆括号可以互换 * 方括号通常来表示“无动作”的数据,如let 赋值 `(let ([x 1] [y 2]) (+ x y))` 5. `(display a) ` display 用于打印 ### 打印函数 ``` (define a "abc") (display a) ;abc (print a) ;"abc" ``` ###描述函数信息 ``` ;; profit : number -> number ;;给定票价,收益是收入和支出之差 ;;预期值 (profit 10) ->20 ;模板: ;(define (profit ticket-price) ...) (define (profit ticket-price) (- 20 ticket-price)) ``` ### 设计诀窍 - 如设计处理混合数据的函数的例子 ![E91219E4-C903-4B09-AFE2-D97989E47FB0.png](http://yanxuan.nosdn.127.net/4bab9f5981a93cda99cda8f4a023eee8.png) :-: 处理自应用数据的函数设计 #### 实例1:非递归案例 用 cond 来区别不同的数据类型 ``` ;数据定义: (define-struct circle (center radius)) (define-struct square (nw length) ;; shape是下列二者之 ;; 1.结构体:(make- circle p s) ;; 其中 p 是 posn 结构体,s是数;或 ;; 2.结构体:(make- square p s) ;; 其中 p 是 posn 结构体,s 是数 ;; 例子: 参见测试 ;; 模板: ;;(define (f a-shape) ;; (cond ;; [(square? a-shape) ...] ;; [(circle? a-shape) ...])) ;; 定义 (define (perimeter a-shape) (cond [(circle? a-shape) (* (* 2 (circle-radius a-shape)) pi)] [(square? a-shape) (* (square-length a-shape) 4)])) ;; 测试:(即例子) (= (perimter (make-square ... 3)) 12) (= (perimter (make-square ... 1)) (* 2 pi)) ``` ### 实例2:递归案例 开发函数 occurs1,该函数读入一个网页和一个符号,返回该符号在网页中出现的次数,忽略 嵌入的网页 ``` ;; occurs1 : sym,wp->number ;; 读入一个网页和一个符号,返回该符号在网页中出现的次数,忽略嵌入的网页 ;; 例子 ;;(= (occurs1 'a empty) 0) ;;(= (occurs1 'a (list 'a)) 1) ;;(= (occurs1 'a (list 'a (list 'a))) 1) ;;(= (occurs1 'a (list 'b 'a)) 1) ;; 模版 ;;(define (occurs1 sym wp) ;; (cond ;; [(empty? wp) ...] ;; [(cons? (first wp)) ...] ;; [(eq? sym (fits wp)) ... (first wp) ... (occurs1 sym (rest wp))] ;; [else ...(occurs1 sym (rest wp))...])) (define (occurs1 sym wp) (cond [(empty? wp) 0] [(cons? (first wp)) 0] [(eq? sym (first wp)) (+ 1 (occurs1 sym (rest wp)))] [else (occurs1 sym (rest wp))])) ;;测试 (= (occurs1 'a empty) 0) (= (occurs1 'a (list 'a)) 1) (= (occurs1 'a (list 'a (list 'a))) 1) (= (occurs1 'a (list 'b 'a)) 1) ``` 开发函数 occurs2,该函数类似于 occurs1,但是它计算该符号所有的出现次数,包括在嵌入网页中的 出现 ``` ;; occurs2 : sym,wp->number ;; 但是它计算该符号所有的出现次数,包括在嵌入网页中的出现 ;; 例子 ;;(= (occurs2 'a empty) 0) ;;(= (occurs2 'a (list 'a)) 1) ;;(= (occurs2 'a (list 'a (list 'a))) 2) ;;(= (occurs2 'a (list 'b 'a)) 1) ;; 模版 ;;(define (occurs2 sym wp) ;; (cond ;; [(empty? wp) ...] ;; [(cons? (first wp)) ... (occurs2 sym (first wp)) ... (occurs2 sym (rest wp))...] ;; [(eq? sym (first wp)) ... (first wp) ... (occurs2 sym (rest wp))...] ;; [else ...(occurs2 sym (rest wp))...])) (define (occurs2 sym wp) (cond [(empty? wp) 0] [(cons? (first wp)) (+ (occurs2 sym (first wp)) (occurs2 sym (rest wp)))] [(eq? sym (first wp)) (+ 1 (occurs2 sym (rest wp)))] [else (+ 0 (occurs2 sym (rest wp)))])) ;;测试 (= (occurs2 'a empty) 0) (= (occurs2 'a (list 'a)) 1) (= (occurs2 'a (list 'a (list 'a))) 2) (= (occurs2 'a (list 'b 'a)) 1) ```