I\'m trying to modify a representation of a tree from : (A 2 B 0 C 2 D 0 E 0) in (A (B) (C (D) (E))). My code is like:
(defun transform(l)
(cond
( (null l)
Here is a possible solution, in which an auxiliary function tree-sequence
is used. Note that the functions do not check for the validity of the input list.
The main function has a very simple structure:
(defun transform(l)
(if (null l)
nil
(tree-sequence l)))
while the auxiliary function is based on the following idea: at each call, the rest of the list to be transformed is passed to the function, that returns a pair of values:
The tree that has been transformed by the function,
The rest of the list following the part of the list used to build the first value.
In this way, at each recursive step, the function itself can use the second value to continue to transform the tree.
Here is the function:
(defun tree-sequence(l)
(case (cadr l)
(0 (values (list (car l)) (cddr l)))
(1 (multiple-value-bind (left-subtree rest-of-list) (tree-sequence (cddr l))
(values (list (car l) left-subtree) rest-of-list)))
(t (multiple-value-bind (left-subtree rest-of-list) (tree-sequence (cddr l))
(multiple-value-bind (right-subtree rest-of-rest) (tree-sequence rest-of-list)
(values (list (car l) left-subtree right-subtree) rest-of-rest))))))
Note the the couple of values returned are used only in the function tree-sequence
, while transform
uses only the first value returned, which is the tree.
Finally, note that this approach works for any kind of elements as nodes of the tree, including integers.