2017-04-03 20 views
0

我正在做一個家庭作業任務,並且第一個函數讓我執行諸如刪除列表中給定元素或顯示列表的給定元素等操作。接下來的功能要求我刪除嵌套列表或顯示它們。你有使用嵌套列表的一般技巧嗎?我想這些功能與我之前寫的功能非常相似,只是稍微調整了一下。如何使用LISP中的嵌套列表

這是我迄今爲止編寫的兩個函數示例。注意我必須使用寫作功能的「cond」風格。

(defun delnth(L A) 
    (cond ((= A 1) (rest L)) 
     (t (cons (first L) (delnth (rest L) (- A 1)))))) 


(defun remv(A L) 
    (cond ((eq A (first L)) (remv A (rest L))) 
     ((null L) nil) 
     (t (cons (first L) (remv A (rest L)))))) 
+1

請修正你的函數縮進。你可以使用Emacs。正如他們現在介紹的,你的代碼對於一個Lisper來說是不可讀的。謝謝。 – sds

回答

1

這兩個函數都可以嵌套cons'(1 2 3)(1 . (2 . (3 .()))(cons 1 (cons 2 (cons 3 '())))。嵌套列表可能是conscar嵌套cons。例如。 ((1 .()) .()) ; ==> ((1))

重要的是要能夠看到((1) (2 3))和理解,這是((1 .()) . ((2 . (3 .())) .()))因此,如果您要訪問3這顯然路徑d,一,d,和在相反,你可以構建訪問cadadr是很重要的。

consconscar部分是樹。當你製作一個走樹的功能時,你需要走carcdr,如果它們是cons。因此:

;; generic function to walk trees and reduce 
;; by combiner every value accessed by term 
;; the default argument to combiner is tree-null 
(defun accumulate-tree (tree term combiner null-value) 
    (labels ((rec (tree) 
      (cond ((null tree) null-value) 
        ((atom tree) (funcall term tree)) 
        (t (funcall combiner (rec (car tree)) 
             (rec (cdr tree))))))) 
    (rec tree))) 

(defun sum-numbers (tree) 
    (accumulate-tree tree 
        #'identity 
        #'+ 
        0)) 

(defun count-numbers (tree) 
    (accumulate-tree tree 
        (lambda (v) (if (numberp v) 1 0)) 
        #'+ 
        0)) 

(sum-numbers '((1) (2 3) (((4)) 5))) ; ==> 15 
(count-numbers '(a b 4 3 (e f 5) . 9)) ; ==> 4 

的組合並不需要降低到原子:

(defun reverse-tree (tree) 
    (accumulate-tree tree 
        #'identity 
        (lambda (a d) (cons d a)) 
        '())) 
(reverse-tree '((1 2) (3 4))) 
; ==> ((nil (nil . 4) . 3) (nil . 2) . 1)