使用car / cdr进行LISP递归

时间:2018-05-08 23:27:37

标签: recursion lisp

我在使用LISP的作业中需要帮助。我需要创建一个程序(两个不同的功能),可以采取输出,如((PRO)(LAN))并将其转换为NATO(PapaRomeoOscar LimaAlfaNovember)。以及能够将北约转换成英语,((PapaRomeoOscar)(LimaAlfaNovember))到亲兰。

它需要使用递归,没有循环,并且没有任何变量。我的教授在LISP上学了一个星期,并向我们展示了基本课程。我对这一点毫无头绪。

我的想法是,我需要将这些列表合在一起,然后拿出列表中的汽车并使用ifm状态进行检查:

(if (= car(L1 L2) "i")
  (format -t “India ”)
(format -t ""))

然后递归地获取列表的cdr以递归方式传递它。任何帮助都会非常有帮助。我一直在网上查找示例代码,无法找到类似代码。我已经去了她的办公时间,她说我们应该根据她的笔记知道如何做,这是简单的阶乘功能。

然后,为了将北约转换为英语,我认为你需要在列表中占据一席之地。然后乘坐汽车并使用与上述类似的if语句。然后取cdr并递归传回。我不确定代码的外观,所以我需要很多帮助。提前致谢!

3 个答案:

答案 0 :(得分:1)

(if (= car(L1 L2) "i")
  (format -t “India ”)
(format -t ""))

此代码段中的一些问题:

  • (= car (L1 L2) "i")读作:将函数=应用于三个参数:名为car(L1 L2)"i"的变量,其中{{1是函数(L1 L2)在参数L1中的应用。如果您想获取列表的L2,请使用car

  • (car list)仅适用于数字:传递任何其他内容(如字符串)将无法按预期工作。在比较字符串时使用=,或者更好的是,在此步骤中不要使用字符串。例如,请参阅string=assocsymbol-name

  • string-capitalize中的-t不正确。如果要写入新字符串,请使用(format -t "")。如果要输出到标准输出,请使用nil

  • t:注意您使用的是(format -t “India“)引号,这不是您应该在程序中使用的引号()。此外,您总是打印一个空格,如果您想要将不同的单词连接在一起,这是一个问题,如作业中所述(例如")。

答案 1 :(得分:0)

您正在使用C语法编写Lisp。不要这样做。甚至不认为你可以使用algol经验,例如。你知道py的C,同化,因为虽然C,C ++,perl和python属于Alhol语言的同一个家族,但Lisp并不是。我花了一些时间才找到了for循环。实际上超过一年。

我想也许输入应该是'((p r o) (l a n))而不是'((pro)(lan))。这些改变了你需要的东西。

您是否了解作业中的输入/输出?由于您要打印到stdout而不返回,这是否意味着您应该从stdin读取输入而不是函数中的参数?例如。设想这个反转列表的函数:

(defun my-reverse (list)
  (labels ((helper (list acc)
              (if (endp list)
                  acc
                  (helper (cdr list) (cons (car list) acc)))))
    (helper list '())))

(my-reverse '(1 2 3)) ; ==> (3 2 1)

这不会读取或打印任何内容,除了REPL从函数调用中打印返回的值。

您需要将问题分成更简单的问题。所以想象一下我为一个符号做这件事。例如。 (to-nato 'p) ; ==> papa然后你可以在一个翻译结构的递归函数中使用它。

祝你好运!

答案 2 :(得分:0)

首先,算法

您似乎理解它的原理。通过列表递归迭代是一个非常常见的习惯是Lisp:你拿一个列表,用FIRST做一些事情,然后用RESTCAR / CDR给自己打电话。是遗留名称,我更喜欢在可能的情况下使用更有意义的名称。

(defun print-every (objects)
  (print (first objects))
  (print-every (rest objects)))

当你递归时,你需要的唯一其他东西是终止某个地方,通常当给你的列表是空列表时(注意,(rest '())(),所以如果一个函数只是在列表的其余部分进行递归,它永远不会停止。)

(defun print-every (objects)
  (when objects
    (print (first objects))
    (print-every (rest objects))))

如果您需要从整个操作中收集结果,通常的方法是使用累加器,这是累积结果的函数参数。

(defun add-every (numbers &optional sum)
  (if numbers
      (add-every (rest numbers (+ (first numbers) sum))
      sum))

其次,语法

与任何其他编程语言一样,您需要格外小心,不要在语言B中使用语言A中的内容。

-t之类的短划线开头的参数是你在bash中看到的,而不是在Lisp中看到的。 (format t "foo")将打印foo(以及换行符)。

在Lisp中,(foo bar(1 2) 3) NOT 将参数12提供给函数bar。如果您需要,您的代码必须是(foo (bar 1 2) 3)

另外,在Lisp中,括号和空格分开的表达式是什么。因此'(pro)是包含 ONE 符号的列表,但'(p r o)是包含 THREE 符号的列表。