【问题标题】:LISP Recursive TriangleLISP 递归三角形
【发布时间】:2021-02-12 11:05:12
【问题描述】:

我的递归调用似乎不起作用,我试图在给定一个整数的情况下制作一个三角形,在你们的帮助下,我终于能够在同一行打印字符串,正确的次数1行。在打印行结束时,我有一个递归调用,它调用三角形来制作另一行,一个字符更短。由于某种原因,这个电话似乎永远无法接通。请在下面找到代码,提前感谢大家的任何帮助,非常感谢!

注意:顺便说一句,在 Lisp 中,有什么方法可以像 return 语句一样停止函数?我希望递归在 k = 1 处停止,而不是继续到 k = 0。

(defun newTriangle (k) 
    (cond ((<= k 0) (princ '(Nope))) 
          ((or (= k 1) (= k -1)) (princ 'a)) 
          ((> k 0) (make-string k :initial-element #\a)) 
          (newTriangle (- k 1))))
        
(print (newTriangle 3))

样本输出三角形(3)

aaa 
aa 
a 

样本输出三角形(-3)

aaa 
 aa 
  a

【问题讨论】:

    标签: recursion return lisp common-lisp


    【解决方案1】:

    首先,您需要确定newTriangle 在做什么。调用(print (newTriangle 3)) 表明newTriangle 应该返回一个字符串,然后通过调用print 将其打印出来。但是,newTriangle 的 OP 定义既是打印输出,也是将三角形的单行作为字符串返回。

    对newTriangle 的递归调用永远不会到达,因为在到达此行之前,k 的值的所有可能情况都已用尽。由于k 只能小于零、等于零或大于零,并且由于所有这些情况都在到达递归调用之前进行了测试,因此永远不会到达。另请注意,cond 语句的最后部分的 OP 代码语法错误。 cond 分支中的第一个表达式是一个测试,约定在这里使用t 表示一个分支,如果到达该分支总是会被评估。但是,这里不需要这么多情况。

    假设newTriangle 函数不应该返回一个字符串,而是应该打印一个三角形作为副作用,它应该怎么做?如果输入的数字大于 0,它应该打印一行字符数等于输入数字的行,然后在输入减一的情况下调用自己;否则它什么都不做:

    (defun print-triangle (k)
      (when (> k 0)
        (princ (make-string k :initial-element #\a))
        (terpri)
        (print-triangle (- k 1))))
    

    这个定义被命名为print-triangle 以强调它打印一个三角形作为副作用,因为 kebab-case 在 Lisps 中是惯用的,而 camelCase 不是。请注意,每次在输入大于零的情况下调用 print-triangle 时,都会打印出一个正确长度的字符串,然后打印一个换行符(使用名称模糊的 terpri,它只是将换行符写入当前输出流),然后再次调用print-triangle,k 减 1。

    REPL 交互示例:

    CL-USER> (print-triangle 3)
    aaa
    aa
    a
    NIL
    

    如果目标是返回一个字符串,一种方法是调用一个辅助函数,将结果保存在一个参数中:

    (defun new-triangle (k)
      (build-triangle k ""))
    
    (defun build-triangle (k result)
      (if (> k 0)
          (build-triangle (- k 1)
                          (concatenate 'string
                                       result
                                       (make-string k :initial-element #\a)
                                       (string #\newline)))
          result))
    

    这里,new-triangle 接受一个整数参数,并调用 build-triangle,在 result 位置传递整数参数和一个空字符串。 build-triangle 函数的操作与之前的print-triangle 非常相似,但不是打印行,而是将它们与result 以及包含换行符的字符串连接起来。当build-triangle 完成时,result 字符串返回到new-triangle。请注意,简单地从 REPL 调用 new-triangle 将打印结果字符串 as data(即,带引号);在new-triangle 的结果上调用print 将把字符串打印为数据,并返回字符串。要查看打印的字符串不带引号,可以使用format;或者你可以使用princ,它将打印不带引号的字符串,并返回字符串本身:

    CL-USER> (new-triangle 3)
    "aaa
    aa
    a
    "
    
    CL-USER> (print (new-triangle 3))
    
    "aaa
    aa
    a
    " 
    "aaa
    aa
    a
    "
    
    CL-USER> (format t "~A" (new-triangle 3))
    aaa
    aa
    a
    NIL
    
    CL-USER> (princ (new-triangle 3))
    aaa
    aa
    a
    "aaa
    aa
    a
    "
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-20
      • 2021-07-18
      • 2023-03-24
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多