lisp - 堆栈溢出与关联和功能测试

标签 lisp stack-overflow

我编写了这个函数,如果给定的参数匹配,则返回 t,否则返回 nil。

(defun match (input-form pattern)
  (cond
    ((and (not input-form) (not pattern)) t)
    ((not pattern) nil)
    ((eq (car pattern) '*) (or (match input-form (cdr pattern)) (match (cdr input-form) pattern)))
    ((not input-form) nil)
    ((and (> (length (string (car pattern))) 1) (eq (char (string (car pattern)) 0) '#\?))
            (match (cdr input-form) (cdr pattern)) )
    ((eql (car input-form) (car pattern)) (match (cdr input-form) (cdr pattern))) ) )

当我这样做时:

(setq patterns 
    '(((bonjour *) bonjour) ((salut *) salut)) )

(assoc '(bonjour Eliza) patterns :test #'match)

它运行良好并返回:((bonjour *) bonjour)

(assoc '(hello Eliza) 模式:test #'match) 效果也很好并且返回 nil。

但是当我将模式添加到变量模式时,如下所示:

(setq patterns 
'(((bonjour *) bonjour) ((salut) salut) ((* mere * pere *) parlez-moi de vos parents) ((mere *) la mere de qui) ((* mere) parlez-moi de votre mere)) )

当我请求匹配的内容时,它可以工作,但是当我请求不匹配的内容时,我会收到堆栈溢出错误消息。

我做错了什么?

最佳答案

如果您(trace match) ,您将立即得到答案(只需记住足够快地按 Ctrl-C :-):

  0: (MATCH (BONJOUR2 ELIZA) (BONJOUR *))
  0: MATCH returned NIL
  0: (MATCH (BONJOUR2 ELIZA) (SALUT))
  0: MATCH returned NIL
  0: (MATCH (BONJOUR2 ELIZA) (* MERE * PERE *))
    1: (MATCH (BONJOUR2 ELIZA) (MERE * PERE *))
    1: MATCH returned NIL
    1: (MATCH (ELIZA) (* MERE * PERE *))
      2: (MATCH (ELIZA) (MERE * PERE *))
      2: MATCH returned NIL
      2: (MATCH NIL (* MERE * PERE *))
        3: (MATCH NIL (MERE * PERE *))
        3: MATCH returned NIL
        3: (MATCH NIL (* MERE * PERE *))
          4: (MATCH NIL (MERE * PERE *))
          4: MATCH returned NIL
          4: (MATCH NIL (* MERE * PERE *))
            5: (MATCH NIL (MERE * PERE *))
            5: MATCH returned NIL
            5: (MATCH NIL (* MERE * PERE *))

也就是说,您需要在逐步执行该模式之前测试 (null input-form) :

(defun match (input-form pattern)
  (cond
    ((and (null input-form) (null pattern)) t)
    ((or (null pattern) (null input-form)) nil)
    ((eq (car pattern) '*) 
     (or (match input-form (cdr pattern)) 
         (match (cdr input-form) pattern)))
    ((and (> (length (string (car pattern))) 1) 
             (char= (char (string (car pattern)) 0) #\?))
     (match (cdr input-form) (cdr pattern)))
    ((eql (car input-form) (car pattern))
     (match (cdr input-form) (cdr pattern)))))

请注意我对您的代码所做的缩进和空格更改,以及使用 null而不是not检查空列表时(也可以考虑 endp )。

关于lisp - 堆栈溢出与关联和功能测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23917060/

相关文章:

if-statement - 在 Lisp 中有 'eq' 的反义词吗?

search - 如何减少 A* 搜索 8-puzzle 中的长时间执行时间

lisp - 我的 LISP 函数如何成为未绑定(bind)变量?

struct - Lisp 中的嵌套结构

c - 有没有办法增加堆栈大小/递归限制?

Kotlin:Intrinsics.areEqual 无限循环(堆栈溢出)

java - 适用于 Android 的 Canny 边缘检测器——关于递归函数的 StackOverflow

scheme - 在 Scheme 中检查对象是否为 "listdiff"

java捕获堆栈溢出,获取消息显示和返回问题

java - 在Java中构造新对象时出现堆栈溢出错误