發新話題
打印

請問有關LISP的一些問題

推到噗浪
推到臉書
我想這個作業的意思可能是,要求不用內建的 PUSH 跟 POP 巨集,並且重新定義 PUSH 跟 POP 指令。
另外題目有說要把它定義改成用來操作某個全域的堆疊,下面姑且把這個堆疊(其實是把串列當堆疊用)定義成  *my-global-stack* (名稱自取,
至於用兩個星號 * 包起來,是為了要提醒我自己那是全域變數)。

在 ; 後面,直到行末都會被視為是註解喔,可以省略掉。
複製內容到剪貼板
代碼:

(DEFVAR *my-global-stack*)  ; 宣告全域變數 *my-global-stack*


(DEFUN initialize ()
    (SETQ *my-global-stack* NIL)     ; 把  *my-global-stack*  設定成 NIL ,也就是空串列 ()
                                  ; 傳回值會是最後一行,也就是上面那行的 NIL 喔。                                                                                
)

(DEFUN push (n)
    (SETQ *my-global-stack* (CONS n *my-global-stack*))   ; 利用 CONS 把  *my-global-stack*  串列的最前方加入 n 並且把整個新的串列設成是 *my-global-stack*
     n    ; 因為題目要求最後要傳回新加入的值,所以就把 n 擺在最後一行當作是傳回值
)


(DEFUN pop ()
    (LET ((first-element (CAR *my-global-stack*) ))    ; 利用 CAR 取出 *my-global-stack* 串列的第一個元素 ,並且把它設成區域變數  first-element
         (SETQ *my-global-stack* (CDR *my-global-stack*))  ; 把 *my-global-stack* 去掉第一個元素,然後把新的串列丟給 *my-global-stack*
         first-element)                                ; 因為題目要求最後要傳回的是第一個元素,所以放在這裡當作是傳回值
)


(DEFUN list-stack()
    *my-global-stack*  ; 傳回整個串列,所以把 *my-global-stack* 當作是傳回值
)
讓它依序去執行如下
複製內容到剪貼板
代碼:
>(initialize)
NIL
到這裡時, *my-global-stack* 可視範圍是全域的這個串列被初始化(給值)成 NIL ,也就是空串列 ()
複製內容到剪貼板
代碼:
>(push 'foo)
FOO
到這裡時,剛剛的 *my-global-stack* 空串列被利用 CONS 加進去 foo ,變成是 (foo) 串列啦,本來是會傳回 (foo) 的,
可是我們在定義函數的最後一行多加了點東西,讓它傳回值變成是一開始丟進來的字符 foo 了,。
複製內容到剪貼板
代碼:
>(push 'bar)
BAR
到這裡的時候, CONS 這個函數又把 BAR 給加到 (FOO) 這個串列的最前面,變成是 (BAR FOO) ,然後指定給 *my-global-stack* ,
然後依照函數定義的最後一行,依然把當初傳入的參數當作是傳回值。
複製內容到剪貼板
代碼:
>(list-stack)
(BAR FOO)
這裡是要列出題目要求的可視範圍是全域 *my-global-stack* 堆疊(其實就是串列拿來當堆疊用而已),所以輸出結果是 (BAR FOO)。
複製內容到剪貼板
代碼:
>(pop)
BAR
取出串列的最前面的一個元素,也就是 BAR 。當然,要把 *my-global-stack* 重設成去掉第一個元素的新串列。
而取出來的 BAR 要擺在最後一行,才會變成是傳回值。
複製內容到剪貼板
代碼:
>(list-stack)
(FOO)
確認一下 *my-global-stack* 現在是蝦咪,所以現在是去掉 BAR 之後,就變成是 (FOO) 了。



而關於 POP 跟 PUSH 名稱重複的問題,我想可能跟實作環境有關,我試過 Allegro Common Lisp 它不讓我複寫已存在的巨集,
可是,改用 Corman Lisp 就讓我用下面的函數定義重新複寫了,所以如果你的實作環境不容許你複寫,也可以把下面定義 PUSH 跟 POP 的
名稱買成是 my-push 跟 my-pop (或是如你原本寫的 pus 跟 po 也都可以)。
其實我對巨集沒有很熟,呵呵,我也是好玩自學而已,也是個新手,
所以以後如果我看完書發現怎樣強制要求用函數重寫巨集,那再多回一篇,呵呵。

TOP

我不懂 AI ,以下只是憑感覺隨便哈拉,也不知道可不可行喔。

樹狀結構由根節點 (5 3) 出發 ,然後利用下面六步產生新節點,

有之前重複出現的節點就不儲存(遞迴的終止條件),


左邊值清空 (若左邊值=0,不做此步)
右邊值清空 (若右邊值=0,不做此步)
左邊往右邊倒 (若右邊已滿=3或左邊=0,不做此步)
右邊往左邊倒 (若左邊已滿=5或右邊=0,不做此步)
左邊加水到滿 (若左邊已滿=5,不做此步)
右邊加水到滿 (若右邊已滿=3,不做此步)

把整個樹狀結構找出來,然後在去搜尋 (4  任意值) 的節點裡,

哪一個最靠近根節點?

只是想法,寫起來可能會很冗長吧。

TOP

That's okay. 放輕鬆,我也沒幫到蝦咪大忙,
我也是學習者,只是下禮拜天(12/03)要考托福了,
沒辦法慢慢寫出來,等考完我在仔細想想,
呵呵,蠻有趣的題目。

TOP

發新話題