David Bovill wrote:
*Task*
I want to put an indented outline (more generally a tree structure) into an
array.

I suspect I've mis-understood your problem .... my "solution" seems so straightforward that I may be missing some important part of the desired data structure. So I'll re-state the problem in my own words, and then give my attempt to solve it - and hopefully if there is something major missing, that should be clear.

Input : an indented outline of text.

Output : a data structure which allows easy (quick, efficient, ....) access to parent and children nodes of an arbitrary node, thereby making it easy to write general (possibly recursive) functions and handlers.

[Aside - often recursion is a good tool to *think* about a problem, but the implementation can be sequential .... ]

Data structure :  3 arrays, indexed by the line number (node number):
  i, 'text' : the text of that node
  i, 'parent' : the line number of its parent
  i. 'children : a TAB-separated list of line numbers of its children.


Given this, it is easy to write the base functions needed to build arbitrary tree-functions.

function getParent pArray, pNode
   return pArray[pNode, 'Parent']
end getParent

function getChildren pArray, pNode
  return pArray[pNode, 'Children']
end getChildren

for example - print out all immediate children ...

put getChildren(Data, thisnode) into tChildren
repeat for each item tChild in tChildren
     put Data[tChild, 'Text'] & CR after field 'Output'
end repeat

So - a very simple data structure to build .... code is straightforward if a little bit tricky

[Sorry - I have a stack ready to put on RevOline but RevOnline has decided I need a new key to share stacks, so here is the code in-line ...]

(note - only tested a little bit)

function buildTree pInput
# given indented outline of a 'forest' (i.e. multiple rooted trees) build the tree-like data structure
   set the itemDel to TAB
   put empty into lParents
   put 0 into lCurNode # the top-level pseudo-node
   put -1 into lCurDepth  # -1 to allow for the top-level pseudo-node
   put 0 into lCount
   repeat for each line L in pInput

      put getDepth(L) into tDepth
      if tDepth < lCurDepth then
         # we have popped back up 1 or more levels
         put tDepth into lCurDepth
         if tDepth = 0 then
            put 0 into lCurNode
         else
            #put item tDepth+2 of lParents into lCurNode
            put lCount into lCurNode

         end if
      else
         if tDepth = lCurDepth then
            # another node at the same level - no change needed
            put lCount into lCurNode
         else
            if tDepth > lCurDepth+1 then # badly formed input  !!
               # should probably do something more extreme here
               return empty
            end if
            # so we are here with a new increase in indent level
            put lCurNode & TAB after lParents

         end if
      end if
      put L into Data[lCount, 'text']
      put item -1 of lParents into tParent
      put tParent into Data[lCount, 'parent']
      put lCount & TAB after Data[tParent, 'children']
      put tDepth into lCurDepth
   end repeat
   return Data
end buildTree

Hope that does something like what you wanted,
-- Alex.
_______________________________________________
use-revolution mailing list
[email protected]
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-revolution

Reply via email to