我需要编写的函数有两个参数:模式(p)和列表(L)。我想找到包含模式的列表部分以及模式之后的所有内容。如果模式不在列表中,则返回nil。
示例:
输入:(find_pattern'(h e l p)'(i e e e e p p e e s))
输出:'(h e l p p l e s e)
我只能使用基本的lisp函数(cond,car,cdr,cons,null,eq,/ =)。它需要递归,不能使用setq等。
我的策略:
我推理的案例是:
p = nil,L = nil:如果模式位于列表的末尾,则会发生这种情况,因此,返回nil
p = nil,L =(none-nil value):如果pattern位于列表的中间,则返回L
p =(非零值),L = nil:未找到模式返回nil
p =(非零值),L =(非零值):如果p和L的汽车相同,则递归调用p和L的cdr。如果它们不相同,用p和L的cdr递归调用。
我的尝试:
(defun find_pattern (p L)
(cond((null p)
(cond ((null L) nil) ; p = nil, L = nil
(T L))) ; p = nil, L != nil
((T
(cond ((null L) nil) ; p != nil, L = nil
((eq (car p), (car L)) ; p!= nil, L != nil
(cons ((car L) (find_pattern (cdr p) (cdr L))))))
)
如果没有运行,我已经看到了一些问题:
如果我发现部分模式匹配,我永远不会回到完整模式。因此,诸如'(a b c)'(d a b d a b c)之类的输入会得到错误的结果。此外,部分结果也会附加到列表中。
有人能让我朝着正确的方向前进吗?当我遇到部分模式时,如何返回搜索完整模式?
答案 0 :(得分:0)
这应该适用于Common Lisp - 我在这里使用的技术是在助手中传递src
的副本,以跟踪当前的搜索位置
(defun find-pattern-helper (xs ys src)
(cond ((null xs)
src)
((null ys)
nil)
((eq (car xs) (car ys))
(find-pattern-helper (cdr xs) (cdr ys) src))
(T
(find-pattern-helper pat (cdr src) (cdr src)))))
(defun find-pattern (pat src)
(find-pattern-helper pat src src))
或者在这里它是在Racket ...我有点咂Lisp所以这是我唯一可以在
中测试它的东西#lang racket
(define (find-pattern pat src)
(let loop ((xs pat) (ys src) (src src))
(cond ((null? xs)
src)
((null? ys)
'())
((eq? (car xs) (car ys))
(loop (cdr xs) (cdr ys) src))
(#t
(loop pat (cdr src) (cdr src))))))
(find-pattern '(h e l p) '(i n e e d h e l p p l e a s e))
;; => '(h e l p p l e a s e)
(find-pattern '() '(h a y s t a c k))
;; => '(h a y s t a c k)
(find-pattern '(h a y s t a c k) '(h a y))
;; => '()