【问题标题】:(Common lisp) Flattening and passing list(Common lisp) 扁平化和通过列表
【发布时间】:2016-05-01 03:17:20
【问题描述】:

我在这里尝试做的是首先展平任何给定的列表,然后将该列表传递给我的加密函数。虽然这不起作用,我不知道为什么。 这是我到目前为止所拥有的,

(defun flatten (l)
  (cond ((null l) l)
       ((atom l) (list l))
      (t (loop for a in l appending (flatten a))))

)



(defun encrypt(enctext)
(flatten enctext)

  (if(eq 'A (first enctext))    ;If the first charcater equals 'A'...
      (progn                    ;To allow multiple statements in an if statement
       (princ #\B)              ; First statement, print this character
       (encrypt(rest enctext))))    ;Second statement, run function again passing the rest of the characters

  (if(eq 'B (first enctext))
      (progn
       (princ #\C)
        (encrypt(rest enctext))))


)

这就是我调用加密函数的方式

(encrypt '((A)(B))

我应该在“加密”函数中调用“扁平化”函数吗?或者在递归调用之后在“flatten”函数中调用“encrypt”? 以及如何正确传递扁平列表?

【问题讨论】:

    标签: lisp common-lisp clisp


    【解决方案1】:

    FLATTEN 不会破坏性地修改列表。它创建一个包含扁平内容的新列表。你必须使用它的返回值而不是原来的ENCTEXT。这很容易通过调用ENCRYPT 来实现,例如:

    (encrypt (flatten '((A) (B))))
    

    并从ENCRYPT 中删除对FLATTEN 的调用。这是您的代码的一个更简洁的版本:

    (defun encrypt (enctext)
      (unless (endp enctext)
        (princ (ecase (first enctext) ; I'm assuming the input shouldn't 
                 (A #\B)              ; contain any symbols that aren't
                 (B #\C)))            ; handled here. Otherwise use CASE
        (encrypt (rest enctext))))    ; instead of ECASE.
    

    如果您想在没有单独的函数调用来展平列表的情况下执行此操作,则需要递归下降到 ENCRYPT 内的输入列表。比如:

    (defun encrypt (enctext)
      (unless (endp enctext)
        (let ((first (first enctext)))
          (if (atom first)
              (princ (ecase first
                       (A #\B)
                       (B #\C)))
              (encrypt first)))
        (encrypt (rest enctext))))
    
    (encrypt '((A) (B)))
    ; BC
    

    当然,如果您没有理由想要同时使用深度和广度的递归来执行此操作,那么循环将使代码更清晰:

    (defun encrypt (enctext)
      (dolist (el enctext)
        (if (atom el)
            (princ (ecase el
                     (A #\B)
                     (B #\C)))
            (encrypt el))))
    

    【讨论】:

    • 谢谢!我试图将所有内容都包含在一个函数中,但我什至不确定你是否可以这样做。
    • @JoshuaCantero 我添加了另一个示例来做到这一点而不展平。
    • 是的,我注意到了,这很有帮助。
    猜你喜欢
    • 2012-05-25
    • 2014-11-10
    • 2016-01-14
    • 2017-09-24
    • 2021-12-25
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多