《ANSI COMMON LISP》第二章 習(xí)題


《ANSI COMMON LISP》讀書筆記


2. 給出3中不同表示(a b c)的cons表達(dá)式咙边。

(cons 'a '(b c))
(cons 'a (cons 'b (cons 'c '())))
(list 'a 'b 'c)

3. 使用carcdr來定義一個函數(shù),返回一個列表的第四個元素椭员。

(defun fourth. (x)
    (car (cdr (cdr (cdr x)))))

4. 定義一個函數(shù)侥猬,接受兩個實參,返回兩者當(dāng)中比較大的那個欧漱。

(defun max. (x y)
    (if (or (null x) (null y))
        nil
        (if (> x y) x y)))

5. 這些函數(shù)做兩個什么?

(a)
(defun enigma (x)
    (and    (not (null x))
            (or (null (car x))
                (enigma (cdr x)))))
                
(b)
(defun mystery (x y)
    (if (null y)
        nil
        (if (eql (car y) x)
            0  
            (let ((z (mystery x (cdr y))))
                (and z (+ z 1))))))

(a):判斷列表x不為空表葬燎,但是存在空表元素误甚,如此則返回t,否則返回nil谱净。
(b):接受原子x和列表y作為參數(shù)窑邦,返回x出現(xiàn)在列表y中的位置。

(b)中最后一句代碼壕探,當(dāng)y中不存在x元素時冈钦,znil,利用and`的短路行為,不執(zhí)行(+ z 1)李请。

6. 下列表達(dá)式瞧筛,x該是什么才會得到相同的結(jié)果?

(a) > (car (x (cdr '(a (b c) d))))
    B
(b) > (x 13 (/ 1 0))
    13
(c) > (x #'list 1 nil)
    (1)

(a): car
(b): or
(c): apply

apply與funcall的區(qū)別
apply接受一個函數(shù)和一個實參列表导盅,并返回把傳入?yún)?shù)應(yīng)用于實參列表的結(jié)果较幌。
apply 可以接受任意數(shù)量的實參,只要最后一個實參是列表即可白翻。
函數(shù)funcall 做的是一樣的事情乍炉,但不需要把實參包裝成列表。
但apply和funcall是有區(qū)別的滤馍。

CL-USER> (apply #'list 1 nil)
(1)
CL-USER> (funcall #'list 1 nil)
(1 NIL)
CL-USER>

**區(qū)別**就在于參數(shù)使用方法是不同的岛琼。

  • 對于funcall,在函數(shù)描述符之后的參數(shù)都是平等的纪蜒,它們組合成一個列表讓函數(shù)調(diào)用衷恭。
  • 對于apply,最后一個參數(shù)必須為列表纯续,并且是將列表中的每個元素與其他參數(shù)作為平等的參數(shù)對待随珠,然后收集組合成一個列表讓函數(shù)調(diào)用灭袁。

因此apply認(rèn)為nil是一個空列表窗看,內(nèi)部無元素茸歧,與第一個參數(shù)組合是列表(1)list調(diào)用。funcall認(rèn)為1nil是獨立的兩個參數(shù)显沈,組合后交給list函數(shù)生成列表(1 nil)软瞎。

7. 只是用本章所介紹的操作符,定義一個函數(shù)拉讯,它接受一個列表作為實參涤浇,如果有一個元素是列表時,就返回真魔慷。

(defun haslist (x)
    (if (null x)
        nil
        (if (not (listp x))
            nil
            (if (listp (car x))
                t
                (haslist (cdr x))))))

8. 給出函數(shù)的迭代與遞歸版本:

a. 接受一個正整數(shù)只锭,并打印出數(shù)字?jǐn)?shù)量的點。
b. 接受一個列表院尔,并返回a在列表里所出現(xiàn)的次數(shù)蜻展。

a迭代:

(defun print-asterisk (x)
    (if (or (null x) (listp x))
        nil
        (do ((i 1 (+ i 1)))
            ((> i x) 'done)
            (format t "*"))))

a遞歸:

(defun print-asterisk (x)
    (if (or (null x) (listp x))
        nil
        (if (> x 0)
            (progn
                (format t "*")
                (print-asterisk (- x 1)))
            'done)))

b迭代:(這樣不完整,沒有辦法遍歷每個元素的元素)

(defun num-of-a (lst)
    (if (or (null lst) (not (listp lst)))
        nil
        (let ((num 0))
            (dolist (obj lst)
                (if (eql 'a obj)
                    (setf num (+ num 1))))
            num)))

b遞歸:(這才是真正的遞歸遍歷所有的分支)

(defun num-of-a (lst)
    (if (or (null lst) (not (listp lst)))
        0
        (if (eql 'a (car lst))
            (+ 1 (num-of-a (cdr lst)))
            (if (listp (car lst))
                (num-of-a (car lst))
                (num-of-a (cdr lst))))))
                
CL-USER> (num-of-a '((a b (a c (a d))) e f))
3
CL-USER> 

9. 一位朋友想寫一個函數(shù)邀摆,返回列表里所有非nil元素的和纵顾。他寫了此函數(shù)的兩個版本,但兩個都不能工作栋盹。請解釋每一個的錯誤在哪里施逾,并給出正確的版本。

(a) 
(defun summit (lst)
    (remove nil lst)
    (apply #'+ lst))

(b) 
(defun summit (lst)
    (let ((x (car lst)))
        (if (null x)
            (summit (cdr lst))
            (+ x (summit (cdr lst))))))

(a): remove并不能真正將lst里面的nil去掉贞盯,而是其返回值中去掉了nil音念。

(defun summit (lst)
    (let ((x nil))
        (setf x (remove nil lst))
        (apply #'+ x)))

(b): 沒有停止條件

(defun summit (lst)
    (if (null lst)
        0
        (let ((x (car lst)))
            (if (null x)
                (summit (cdr lst))
                (+ x (summit (cdr lst)))))))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沪饺,一起剝皮案震驚了整個濱河市躏敢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌整葡,老刑警劉巖件余,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異遭居,居然都是意外死亡啼器,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門俱萍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來端壳,“玉大人,你說我怎么就攤上這事枪蘑∷鹎” “怎么了岖免?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長照捡。 經(jīng)常有香客問我颅湘,道長,這世上最難降的妖魔是什么栗精? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任闯参,我火速辦了婚禮,結(jié)果婚禮上悲立,老公的妹妹穿的比我還像新娘鹿寨。我一直安慰自己,他們只是感情好薪夕,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布释移。 她就那樣靜靜地躺著,像睡著了一般寥殖。 火紅的嫁衣襯著肌膚如雪玩讳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天嚼贡,我揣著相機與錄音熏纯,去河邊找鬼。 笑死粤策,一個胖子當(dāng)著我的面吹牛樟澜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播叮盘,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼秩贰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柔吼?” 一聲冷哼從身側(cè)響起毒费,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎愈魏,沒想到半個月后觅玻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡培漏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年溪厘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牌柄。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡畸悬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出珊佣,到底是詐尸還是另有隱情蹋宦,我是刑警寧澤闺骚,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站妆档,受9級特大地震影響僻爽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贾惦,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一胸梆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧须板,春花似錦碰镜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至甜奄,卻和暖如春柠横,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背课兄。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工牍氛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烟阐。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓搬俊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜒茄。 傳聞我的和親對象是個殘疾皇子唉擂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容