Flattening a tree structure in Lisp

前端 未结 3 1563
太阳男子
太阳男子 2021-01-28 18:59

I was struggling with flattening a tree structure. I was doing it recursively by comparing each atomic symbol to the rest in the tree but, a friend of mine suggested the followi

3条回答
  •  难免孤独
    2021-01-28 19:23

    The code is rather poorly formatted. In the first part of your question, it's not at all clear why

    ((atom tree) (list tree))
    

    would appear in any Common Lisp code, since it looks like an attempt to call (atom tree), get a function back, and call that function with (list tree). In context, with proper formatting, it's clearer:

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

    It's one clause in a cond. It says that if tree is an atom (which could be a symbol, a number, a vector, etc., anything else that isn't a cons), then return (list tree). As larsmans explained, flatten should always return a list, and this ensures that (flatten 3), for instance, will return (3). Since the (loop for a in tree ...) will work for any tree that is a list, there's really no need to have a case for (null tree), since nil/() is a list. This definition could be simplified to:

    (defun flatten (tree)
      (if (atom tree)
          (list tree)
          (loop for a in tree
                appending (flatten a)))))
    

    There are some similar questions out there on Stack Overflow, and some have almost identical code to what you posted (modulo the formatting). Did the friend was basing a suggestion on one of those. At any rate, for the sake of completeness, you might have a look at:

    • flatten list in lisp
    • Flatten Nests Function in Lisp - need help understanding (almost identical code)
    • Common Lisp - flatting a list that may contain symbols (similar code)

提交回复
热议问题