How to remove nested parentheses in LISP

前端 未结 12 1555
清酒与你
清酒与你 2020-11-29 10:20

How can I remove nested parentheses recursively in Common LISP Such as

  (unnest \'(a b c (d e) ((f) g))) => (a b c d e f g)
  (unnest \'(a b))                    


        
12条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-29 10:46

    I know this question is really old but I noticed that nobody used the push/nreverse idiom, so I am uploading that here.

    the function reverse-atomize takes out each "atom" and puts it into the output of the next call. At the end it produces a flattened list that is backwards, which is resolved with the nreverse function in the atomize function.

    (defun reverse-atomize (tree output)
        "Auxillary function for atomize"
        (if (null tree)
          output
          (if (atom (car tree))
              (reverse-atomize (cdr tree) (push (car tree) output))
              (reverse-atomize (cdr tree) (nconc (reverse-atomize (car tree)
                                                                   nil)
                                                  output)))))
    
    (defun atomize (tree)
        "Flattens a list into only the atoms in it"
         (nreverse (reverse-atomize tree nil)))
    

    So calling atomize '((a b) (c) d) looks like this:

    (A B C D)
    

    And if you were to call reverse-atomize with reverse-atomize '((a b) (c) d) this would occur:

    (D C B A)
    

    People like using functions like push, nreverse, and nconc because they use less RAM than their respective cons, reverse, and append functions. That being said the double recursive nature of reverse-atomize does come with it's own RAMifications.

提交回复
热议问题