Lisp-保持单词按给定字母完成

Lisp-保持单词按给定字母完成,lisp,common-lisp,clisp,Lisp,Common Lisp,Clisp,我试图修改这个函数,使其在给定列表时只保留以给定字母结尾的单词。我对允许使用的内容几乎没有限制,需要保留char、rplacd和length才能使用。我现在对“长度”部分有困难。我最初设法让所有单词都以给定的字母开头,但我在第5行做相反的事情时遇到了麻烦 (setq liste(读过鼻子艺术静默)) 我将得到以下结果 (以“e liste”结尾)=>(鼻子保持沉默) 考虑到给定的资源有限,这需要递归解决方案。(endingwith'e liste)的值应根据调用列表其余部分的endingwith

我试图修改这个函数,使其在给定列表时只保留以给定字母结尾的单词。我对允许使用的内容几乎没有限制,需要保留char、rplacd和length才能使用。我现在对“长度”部分有困难。我最初设法让所有单词都以给定的字母开头,但我在第5行做相反的事情时遇到了麻烦

(setq liste(读过鼻子艺术静默))
我将得到以下结果
(以“e liste”结尾)=>(鼻子保持沉默)


考虑到给定的资源有限,这需要递归解决方案。(endingwith'e liste)的值应根据调用列表其余部分的endingwith的值来定义,如果第一个元素与'e'匹配,则添加或不添加该元素。
进一步注意,在您的情况下,长度应该与字符串一起使用,因此使用(length(string(car-liste)))而不是(string(length(car-liste))。
该函数如下所示:

(defun endingwith (x liste)
   (cond
      ((not liste) nil)
      ((eql (char (string x) 0) (char (string (car liste)) (- (length (string (car liste))) 1)))
          (cons (car liste) (endingwith x (cdr liste))) )
      (t (endingwith x (cdr liste))) ))

考虑到给定的资源有限,这需要递归解决方案。(endingwith'e liste)的值应根据调用列表其余部分的endingwith的值来定义,如果第一个元素与'e'匹配,则添加或不添加该元素。
进一步注意,在您的情况下,长度应该与字符串一起使用,因此使用(length(string(car-liste)))而不是(string(length(car-liste))。
该函数如下所示:

(defun endingwith (x liste)
   (cond
      ((not liste) nil)
      ((eql (char (string x) 0) (char (string (car liste)) (- (length (string (car liste))) 1)))
          (cons (car liste) (endingwith x (cdr liste))) )
      (t (endingwith x (cdr liste))) ))

风格要点:不要使用
(不列出)
;相反,使用
(null liste)
(endp liste)
,分别强调
liste
是一个空列表,或者处理已到达
liste
的末尾。另外,当意图表示空列表时,使用
”()
;当意图表示布尔值False时,使用
nil

liste
的元素是符号,
x
本身是符号;这些符号需要转换为序列,以便评估符号的最终字符<代码>字符串将完成此任务。但是OP代码在这里有两个问题:
length
采用序列参数,因此
(car liste)
的值也必须使用
字符串进行转换;在公共Lisp中,序列的索引为零,因此序列的最后一个索引比其长度小一个

(defun endingwith (x liste)
  (cond
    ((null liste) '())
    ((equal (char (string (car liste))
                  (- (length (string (car liste))) 1))
            (char (string x) 0))
     (rplacd liste (endingwith x (cdr liste))))
    (t
     (endingwith x (cdr liste)))))
在CommonLisp中调试这样的程序的一种方法是进入REPL并进行实验。当您使用函数并将您发送到调试器时,请查找该函数中可能有问题的行

在发布的代码中,
(char(string(length(car liste)))0)
是第一个可能的候选者。在REPL处尝试
(car liste)
,查看其计算结果是否符合预期。如果需要,请尝试
(长度(汽车列表))
。这将再次向调试器发送一个类型错误和如下消息

LENGTH:HAVE不是序列

这表明您需要使用
(string(car liste))
,使用方式与原始函数定义的下一行中使用
(string x)
相同。因此,请在REPL处尝试
(长度(字符串(car-liste))
。现在您应该看到预期值4,但很明显,原始代码行有点混乱,因为
char
希望第一个参数是字符串,第二个参数是索引。因此,请在REPL
(char(string(car-liste))(length(string(car-liste)))
处重试。这再次让我们进入调试器,并显示如下消息:

CHAR:index 4应小于字符串的长度


但该消息提醒我们,在Common Lisp中,序列的索引为零,长度为4的字符串的最后一个索引为3。因此,再次在REPL:
(char(string(car-liste))((length(string(car-liste)))1))
。现在我们已经成功了,REPL返回了预期的
\E
。在REPL中解决了这一有问题的行之后,我们现在可以替换原始函数定义中的这一行,看看这是否有效。确实如此。

一些风格要点:不要使用
(不列出)
;相反,使用
(null liste)
(endp liste)
,分别强调
liste
是一个空列表,或者处理已到达
liste
的末尾。另外,当意图表示空列表时,使用
”()
;当意图表示布尔值False时,使用
nil

liste
的元素是符号,
x
本身是符号;这些符号需要转换为序列,以便评估符号的最终字符<代码>字符串
将完成此任务。但是OP代码在这里有两个问题:
length
采用序列参数,因此
(car liste)
的值也必须使用
字符串进行转换;在公共Lisp中,序列的索引为零,因此序列的最后一个索引比其长度小一个

(defun endingwith (x liste)
  (cond
    ((null liste) '())
    ((equal (char (string (car liste))
                  (- (length (string (car liste))) 1))
            (char (string x) 0))
     (rplacd liste (endingwith x (cdr liste))))
    (t
     (endingwith x (cdr liste)))))
在CommonLisp中调试这样的程序的一种方法是进入REPL并进行实验。当您使用函数并将您发送到调试器时,请查找该函数中可能有问题的行

在发布的代码中,
(char(string(length(car liste)))0)
是第一个可能的候选者。在REPL处尝试
(car liste)
,查看其计算结果是否符合预期。如果需要,请尝试
(长度(汽车列表))
。这将再次向调试器发送一个类型错误和如下消息

LENGTH:HAVE不是序列

这表明您需要使用
(string(car liste))
,使用方式与在原点的下一行中使用
(string x)
相同
(defun ends-with-p (end s)
  (string= end (subseq s (- (length s) (length end)))))

(defun keep-ending-with (end strings)
  (remove-if-not #'(lambda (x) (ends-with-p end x)) strings))