1.Lists, Iteration, and Recursion 表,迭代,递归
表迭代函数map andmap ormap //andmap ormap对各个表元素求得的结果一起进行and/or
多重表处理 handle multiple lists
(map (lambda(x y)(+ x y))
(list 1 2 3)
(list 4 5 6))
'(5 7 9)
过滤 filter
留下true的元素,抛弃false的元素
(filter (lambda(x)(> x 3))
'(1 4 7))
'(4 7)
foldl
//It uses the per-element function to both process an element and combine it with the “current” value, so the per-element function takes an extra first argument.
(foldl (lambda (elem v)
(+ v (* elem elem)))
0
'(1 2 3))
表迭代 first rest empty cons
重写length函数
#lang racket
(require racket/base)
(define(length x)
(cond
[(empty? x) 0]
[else (+ 1 (length(rest x)))]))
尾递归
(my-length (list "a" "b" "c"))
= (+ 1 (my-length (list "b" "c")))
= (+ 1 (+ 1 (my-length (list "c"))))
= (+ 1 (+ 1 (+ 1 (my-length (list)))))
= (+ 1 (+ 1 (+ 1 0)))
= (+ 1 (+ 1 1))
= (+ 1 2)
= 3
For a list with n elements, evaluation will stack up n (+ 1 ...) additions, and then finally add them up when the list is **exhausted**
//尾递归写法
(require racket/base)
(define (my-length lst)
(define (iter lst len)
(cond
[(empty? lst) len]
[else (iter (rest lst)(+ len 1))]))
(iter lst 0))
递归和迭代对比
At the same time, recursion does not lead to particularly bad performance in Racket, and there is no such thing as stack overflow; you can run out of memory if a computation involves too much context, but exhausting memory typically requires orders of magnitude deeper recursion than would trigger a stack overflow in other languages. These considerations, combined with the fact that tail-recursive programs automatically run the same as a loop, lead Racket programmers to embrace recursive forms rather than avoid them.
编程:删除表中的连续的副本
输入 “a” “b” “b” “b” “b” “b”
输出 “a” “b”
分析:如何知道前后相邻的两个元素相同?
i = first l
equal?i first(rest l)
接下来,如果不相同就加上去,相同的话继续下一次判断和操作
过程如下:
(remove-dups (list "a" "b" "b" "b" "b" "b"))
= (cons "a" (remove-dups (list "b" "b" "b" "b" "b")))
= (cons "a" (remove-dups (list "b" "b" "b" "b")))
= (cons "a" (remove-dups (list "b" "b" "b")))
= (cons "a" (remove-dups (list "b" "b")))
= (cons "a" (remove-dups (list "b")))
= (cons "a" (list "b"))
= (list "a" "b")
代码如下:
(define (my-dups l)
(cond
[(empty? l)empty)]
[(empty?(rest l))l]
[else
(let ([i (first l)])
(if(equal? i (first(rest l)) (my-dups(rest l)) (cons i (my-dups(rest l)))]))
2.Pairs, Lists, and Racket Syntax
Pairs 对 Lsit 表
> (cons (list 2 3) 1)
'((2 3) . 1)
> (cons 1 (list 2 3))
'(1 2 3)
Why?
symbol 和 character
Indeed, the intrinsic value of a symbol is nothing more than its character content. In this sense, symbols and strings are almost the same thing, and the main difference is how they print. The functions symbol->string and string->symbol convert between them.
> (symbol? '(1 2))
#f
> (symbol? '1)
#f
> (symbol? 'a)
#t
The quote form has no effect on a literal expression such as a number or string.
’ 对字符串和数字没效果
Racket syntax
The syntax of Racket is not defined directly in terms of character streams. Instead, the syntax is determined by two layers:
a reader layer, which turns a sequence of characters into lists, symbols, and other constants; and
an expander layer, which processes the lists, symbols, and other constants to parse them as an expression.
However, a pair of .s can also appear around a single element in a parenthesized sequence, as long as the element is not first or last. Such a pair triggers a reader conversion that moves the element between .s to the front of the list.
> (1 . < . 2)
#t
> '(1 . < . 2)
'(< 1 2)