Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1693960
  • 博文数量: 177
  • 博客积分: 9416
  • 博客等级: 中将
  • 技术积分: 2513
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-06 16:08
文章分类

全部博文(177)

文章存档

2013年(4)

2012年(13)

2011年(9)

2010年(71)

2009年(12)

2008年(11)

2007年(32)

2006年(25)

分类: Python/Ruby

2011-07-10 21:22:24

顶级hacker(非cracker)Eric Raymond曾经说过,一个严肃的程序员至少需要掌握5门编程语言:C、Java、Python、Perl、LISP。这其中的原因不言自明。不过,我倒不认为必须掌握Java——毕竟,我认为Java还是有不少缺陷的,它的后裔C#(也许M$的拥趸们不会这么认为,但从表现上看,有比较明显的继承痕迹)应该更值得学习——不过说这话的时候C#并没有出现。至于LISP,经过简单的一些学习,个人认为,它的编程范式与我们常用的命令式有很大的区别,其所代表的哲学与思维方式值得我们学习——即便我们从来也不会用到函数式编程。请原谅我在这里说的大话“其所代表的哲学与思维方式”,但这是目前我所能想到的最合适的话了。

闲话少说。SICP被公认是学习LISP的Scheme方言的经典入门书。但阅读了中文版第一章之后,发现以自己的能力和水平,还不足以读懂中文版。于是,我便翻到了另外一本书:Simply Scheme。书的序言中说道:We believe that everyone who is seriously interested in computer science must read SICP eventually. Our book is a prequel; it's meant to teach you what you need to know in order to read that book successfully. 虽然SICP的作者Hal认为这是对他们的恭维:Julie and Gerry Sussman and I are flattered that Harvey and Wright characterize their revolutionary introduction to computer science as a "prequel" to our text Structure and Interpretation of Computer Programs. 显然,对我来说,Simply Scheme就是让我准备好阅读SICP的那本书。

在解答练习题之前,先列出Scheme的基本语法:
(define var value)  ;; 定义一个变量(Define's real job is to give a name to some value)
(define (func arg-list) (function body))  ;;定义一个函数
(if (predicate x) exp1 exp2) ;; 条件分支
(cond ((predicate x) exp1) ((predicate2 y) exp2) ... (else expn)) ;; case
(let ((name val) (name val) (...) ... ) body) ;; 创建并执行一个匿名函数(let is merely an abbreviation for creating and invoking an anonymous procedure)
(lambda (arg-list) (body))  ;; 创建一个匿名的函数
' ;; 用于创建list(简写)

好了,语法基本学完了,可以开始看练习题了。真正比较有意思的题是从第九章开始的。在完成联系题的时候,并没有考虑错误处理,以及非法输入的问题等,仅仅是保证问题得到了解决。

9.4 The following program doesn't work. Why not? Fix it.

(define (who sent) (every describe '(pete roger john keith))) (define (describe person) (se person sent))

It's supposed to work like this:

> (who '(sells out)) (pete sells out roger sells out john sells out keith sells out)answer:every的第一个参数是一个function,而这里describe返回的是一个list。因此,应该将这两个函数改为:

  1. (define (who sent)
  2.   (every (lambda (person)
  3.            (se person sent))
  4.          '(pete roger john keith)))
9.5  Write prepend-every:

> (prepend-every 's '(he aid he aid)) (SHE SAID SHE SAID) > (prepend-every 'anti '(dote pasto gone body)) (ANTIDOTE ANTIPASTO ANTIGONE ANTIBODY)answer:

  1. (define (prepend-every wd sent)
  2.   (every (lambda (wd2)
  3.            (word wd wd2))
  4.          sent))
9.6  Write a procedure sentence-version that takes a function f as its argument and returns a function gf should take a single word as argument. g should take a sentence as argument and return the sentence formed by applying f to each word of that argument.

> ((sentence-version first) '(if i fell)) (I I F) > ((sentence-version square) '(8 2 4 6)) (64 4 16 36)
answer:
  1. (define (sentence-version func)
  2.   (lambda (sent)
  3.     (every func sent)))

9.7  Write a procedure called letterwords that takes as its arguments a letter and a sentence. It returns a sentence containing only those words from the argument sentence that contain the argument letter:

> (letterwords 'o '(got to get you into my life)) (GOT TO YOU INTO)
answer:
  1. (define (letterwords letter sent)
  2.   (keep (lambda (wd)
  3.           (member? letter wd))
  4.         sent))

9.8  Suppose we're writing a program to play hangman. In this game one player has to guess a secret word chosen by the other player, one letter at a time. You're going to write just one small part of this program: a procedure that takes as arguments the secret word and the letters guessed so far, returning the word in which the guessing progress is displayed by including all the guessed letters along with underscores for the not-yet-guessed ones:

> (hang 'potsticker 'etaoi) _OT_TI__E_

Hint: You'll find it helpful to use the following procedure that determines how to display a single letter:

(define (hang-letter letter guesses) (if (member? letter guesses) letter '_))answer:
  1. (define (hang-letter letter guesses)
  2.   (if (member? letter guesses)
  3.       letter
  4.       '_))
  5. (define (hang wd guesses)
  6.   (accumulate word
  7.               (every (lambda (letter)
  8.                        (hang-letter letter guesses))
  9.                      wd)))
9.10  In Chapter 2 we used a function called appearances that returns the number of times its first argument appears as a member of its second argument. Implement appearances.answer:
  1. (define (appearances arg1 arg2)
  2.   (count (keep (lambda (x)
  3.                  (equal? arg1 x))
  4.                arg2)))

9.11  Write a procedure unabbrev that takes two sentences as arguments. It should return a sentence that's the same as the first sentence, except that any numbers in the original sentence should be replaced with words from the second sentence. A number 2 in the first sentence should be replaced with the second word of the second sentence, a 6 with the sixth word, and so on.

> (unabbrev '(john 1 wayne fred 4) '(bill hank kermit joey)) (JOHN BILL WAYNE FRED JOEY) > (unabbrev '(i 3 4 tell 2) '(do you want to know a secret?)) (I WANT TO TELL YOU)answer:
  1. (define (unabbrev sent1 sent2)
  2.   (every (lambda (x)
  3.            (if (not (number? x))
  4.                x
  5.                ((lambda (y)
  6.                   (item y sent2))
  7.                   x)))
  8.          sent1))

9.12  Write a procedure first-last whose argument will be a sentence. It should return a sentence containing only those words in the argument sentence whose first and last letters are the same:

> (first-last '(california ohio nebraska alabama alaska massachusetts)) (OHIO ALABAMA ALASKA)Answer:
  1. (define (first-last sent)
  2.   (keep (lambda (wd)
  3.           (equal? (first wd)
  4.                   (last wd)))
  5.         sent))
试想一下,如果用C/C++或者Java之类的语言来解答这些题的话……好了,今天就先到这里吧。



阅读(2707) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

fera2011-07-13 14:40:02

appearances有个递归的版本:
(define (appearances letter comb)
  (+ (if (equal? letter (first comb))
         1
         0)
     (if (= 0 (count (bf comb)))
         0
         (appearances letter
                      (bf comb)))))

tianbianfei2011-07-12 16:24:53

牛人,俺刚从java转android,请教高手一个问题:大家快来参与讨论吧:http://doumiw.com/market/community/t!showTopic.do?topicId=24

fera2011-07-10 22:18:24

靠!代码缩进全消失了!看来下次得直接粘贴过来了。