【问题标题】:How to insert cons into list on lisp?如何将缺点插入到 lisp 的列表中?
【发布时间】:2016-04-10 13:12:43
【问题描述】:
  1 (setq R (cons 1 20))
  2 (setq L (cons 5 '(a b)))
  3 (setq U (cons 10 'h))
  4
  5
  6 (defun insertcell(R L)
  7   (setq x (list r l))
  8   (cond ((< (car R) (car L))
  9                  (setq x (list R L))
  10                 (print x)
  11                 (print (car(car(cdr x))))
  12         ((> (car R) (car L)
  13                  (insertcell R (car(cdr x)))))      
  14 ))
  15
  16
  17 (print r)
  18 (print l)
  19 (insertcell r l)
  20 (insertcell u r)
  21

Q1) 我不知道如何返回函数的返回值/

Q2) 关于上位代码, 例如,我有一个列表,K= ((1.20)(5 A B)) 我想添加一个(3.H)。 所以,K= ((1.20)(3.H)(5 A B))

查看我的代码, *** - SYSTEM::%EXPAND-FORM: (> (CAR R) (CAR L)) 应该是一个 lambda 表达式。

这是什么? ,我在stackflow上搜索,但没有解决错误。

*** Lisp 很困难。 我研究了 C、C++ 汇编和 ruby​​,我可以编写这些语言。但是,因为 Lisp,我很困惑。

【问题讨论】:

  • 如果没有适当的缩进和代码格式,您在任何编程语言中都不会走得太远。您可能想要格式化和缩进您的代码。总是。 Lisp 的好处:一个好的编辑器可以为你缩进代码。
  • 您的代码应该做什么也完全不清楚。 “插入细胞”? 3.H 是什么? 1.20 是一个数字。但是3.H???

标签: lisp


【解决方案1】:

insertcell 函数中cond 的第一个分支缺少右括号。应该是:

(defun insertcell (R L)
  (setq x (list r l))
  (cond ((< (car R) (car L))
         (setq x (list R L))
         (print x)
         (print (car (car (cdr x)))))    ; <- add a closing paren on this line
        ((> (car R) (car L))             ; <- add a closing paren here too
         (insertcell R (car (cdr x))))))

【讨论】:

    【解决方案2】:

    在 lisp 中,您只需键入表达式即可获得返回值。把函数想象成用括号求解方程。

    对于(2 + 3) / 5,您需要先解决(2 + 3),然后再除以5 以获得结果,对于lisp 表达式也是如此。 (/ (+ 2 3) 5) 是相同的表达式,计算结果为 1。把它想象成减少一个方程,直到它被解决。例如:

    (/ (+ 2 3) 5) ;   
    (/ 5 5)       ; since `2 + 3` is `5` we replace `(+ 2 3)` with `5`
    => 1          ; "return" value/result of expression
    

    所以插入函数本身就是:

    (define (insert pos item xs)
        (cond ((null? xs) (cons item '())) ; create a list if passed null else
              ((= pos 0) (cons item xs))     ; if (n = 0) insert `item' else next
              (cons (car xs) (insert (- pos 1) item (cdr xs)))))
    

    我们遍历列表并递减n,直到等于0。然后我们使用consitem 添加到列表中。

    遍历在 C 中如下所示:

    void insert(size_t position,void *item,struct List *list){
        if(list==NULL){
            cons(item,NULL);
        } else {
        if(n==0){
            cons(item,list->tail);
        } else {
            cons(list->head, insert(position - 1, item, list->tail));
        }}
    }
    

    struct List 在哪里:

    struct List{
        void *car;
        void *cdr;
    };
    

    Lambda 只是没有名称的函数,您可以像传递数据一样传递它们。它们类似于 C 中的函数指针,您可以在其中编写像 map(void (*f)(void*),struct *list); 这样的高阶函数,它将 f 应用于列表的每个成员。

    在 Lisp 中:

    (define (map f xs)
        (if (null? xs) ; if empty return empty else apply `f'
            '()        ; and go to next node
            (cons (f (car xs)) (map f (cdr xs)))))
    

    在 C 中:

    void map(void (*f)(void*),struct List *list){
        if(list==NULL)return;
        list->car = f(list->car);
        map(f,(struct List*)list->cdr)
    }
    

    如果您有一个 1..10 的列表并且您写 (map (lambda (x) (+ 1 x)) xs),您将向列表的每个成员添加 1,从而生成一个数字 2..11 的列表。

    注意:上述示例使用了 Scheme Lisp。您应该看看“计算机程序的结构和解释”(SICP),这是对 lisp 和计算机科学的精彩介绍。

    【讨论】:

    • @RainerJoswig 已修复,只需将 n 替换为 pos(最初使用 n 编写,但改为 pos 以便于理解)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    相关资源
    最近更新 更多