- every:对每个元素进行递归操作并保留
- keep:保留其中某些递归结果
- accumulate:将递归结果组合起来
14.1
> (remove-once 'morning '(good morning good morning)) (GOOD GOOD MORNING)14.2
> (up 'town) (T TO TOW TOWN)14.3
> (remdup '(ob la di ob la da)) ;; remove duplicates (OB LA DI DA)(It's okay if your procedure returns (DI OB LA DA) instead, as long as it removes all but one instance of each duplicated word.)
Answer:
;; Keep模式
;; 采用高阶函数:
;; using high order function
(define (rm-dup sent)
(if (empty? sent)
'()
(se (first sent)
(rm-dup (keep (lambda (x)
(not (equal? (first sent) x)))
(bf sent))))))
;; 采用直观方法:从第一个单词开始,到最后一个单词,每次将其后的句子中的该单词删除
;; 采用数学函数表示则为:
;; rm-dup(x) =
;; concatenate(first(x),
;; rm-dup(rm-all(first(x),
;; but-first(x))))
(define (rm-all wd sent)
(if (or (empty? wd) (empty? sent))
sent
(se (if (equal? wd (first sent))
'()
(first sent))
(rm-all wd (bf sent)))))
(define (rm-dup sent)
(if (empty? sent)
'()
(se (first sent)
(rm-dup (rm-all (first sent)
(bf sent))))))
;; 将句子分成done(删除重复单词)和not-done两个部分。每次从not-done部分取第一个单词,如果不在done部分,则添加到done部分,否则取not-done下一个单词。
;; cat-new(done, not-done) =
;; cat-new(concatenate(done,
;; new-word(first(not-done))),
;; but-first(not-done))
(define (rm-dup sent)
(define (cat-new done not-done)
(if (empty? not-done)
done
(cat-new (se done
(if (member? (first not-done)
done)
'()
(first not-done)))
(bf not-done))))
(cat-new '() sent))
14.4
> (odds '(i lost my little girl)) (I MY GIRL);; keep模式。无难度(define (odds sent) (if (< (count sent) 2) sent (se (first sent) (odds (bf (bf sent))))))
14.5 Write a procedure letter-count that takes a sentence as its argument and returns the total number of letters in the sentence:
> (letter-count '(fixing a hole)) 1114.6 Write member?.
14.7 Write differences, which takes a sentence of numbers as its argument and returns a sentence containing the differences between adjacent elements. (The length of the returned sentence is one less than that of the argument.)
> (differences '(4 23 9 87 6 12)) (19 -14 78 -81 6)Answer:;; Accumulate14.8 Write expand, which takes a sentence as its argument. It returns a sentence similar to the argument, except that if a number appears in the argument, then the return value contains that many copies of the following word:
> (expand '(4 calling birds 3 french hens)) (CALLING CALLING CALLING CALLING BIRDS FRENCH FRENCH FRENCH HENS) > (expand '(the 7 samurai)) (THE SAMURAI SAMURAI SAMURAI SAMURAI SAMURAI SAMURAI SAMURAI)14.9 Write a procedure called location that takes two arguments, a word and a sentence. It should return a number indicating where in the sentence that word can be found. If the word isn't in the sentence, return #f. If the word appears more than once, return the location of the first appearance.
> (location 'me '(you never give me your money))14.12 Write a procedure progressive-squares? that takes a sentence of numbers as its argument. It should return #t if each number (other than the first) is the square of the number before it:
> (progressive-squares? '(3 9 81 6561)) #T > (progressive-squares? '(25 36 49 64)) #FAnswer:
;; Accumulate模式,需要对初始值进行设置。预设为#t,对于空的句子返回#f。当只剩一个数时返回结果
;; 一旦出现不满足条件的情况,立刻返回#f。否则,将所有每次执行结果用and来执行accumulate操作
(define (progressive-squares? sent)
(let ((nums (keep number? sent)))
(define (iter result st)
(cond ((empty? st) #f)
((not result) #f)
((= (count st) 1) result)
(else (and result
(iter (equal? (square (first st))
(first (bf st)))
(bf st))))))
(iter #t nums)))
14.14 Write a predicate same-shape? that takes two sentences as arguments. It should return #t if two conditions are met: The two sentences must have the same number of words, and each word of the first sentence must have the same number of letters as the word in the corresponding position in the second sentence.
> (same-shape? '(the fool on the hill) '(you like me too much))#T
> (same-shape? '(the fool on the hill) '(and your bird can sing))
#F
(define (same-shape? sent1 sent2)
(define (iter result st1 st2)
(cond ((not (= (count st1) (count st2))) #f)
((empty? st1) result)
(else (and result
(iter (= (count (first st1))
(count (first st2)))
(bf st1)
(bf st2))))))
(iter #t sent1 sent2))
14.15 Write merge, a procedure that takes two sentences of numbers as arguments. Each sentence must consist of numbers in increasing order. Merge should return a single sentence containing all of the numbers, in order. (We'll use this in the next chapter as part of a sorting algorithm.)
> (merge '(4 7 18 40 99) '(3 6 9 12 24 36 50))(3 4 6 7 9 12 18 24 36 40 50 99) (define (merge sent1 sent2)
(cond ((empty? sent1) sent2)
((empty? sent2) sent1)
((< (first sent1) (first sent2)) (se (first sent1)
(merge (bf sent1) sent2)))
(else (se (first sent2)
(merge sent1 (bf sent2))))))
注意,当返回值为逻辑值时,accumulate模式没有明显的accumulate,也可以有,如progressive-square、same-shape?