2013-02-26 4 views
1

Предположим, у меня есть двоичное дерево.Как хорошо печатать глубину рекурсии в Haskell?

main = putStrLn $ printTree tree                                             

data Tree = Empty | Node Int (Tree) (Tree) deriving (Show)                                      

tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty                                       

printTree :: Tree -> String                                              
printTree x = case x of                                               
    Node num treeA treeB -> show num ++ "\n" ++ printTree treeA ++ "\n" ++ printTree treeB                               
    Empty -> "Empty" 

Выход

*Main> main                                                  
4                                                    
3                                                    
Empty                                                   
2                                                    
Empty                                                   
Empty                                                   
Empty 

Желаемая Выход (с помощью табуляции или двойного пространства отлично)

*Main> main                                                  
    4                                                    
     3                                                    
     Empty                                                   
     2                                                    
      Empty                                                   
      Empty                                                   
     Empty 
+0

Начните с возврата '[String]', а не 'String'. Создание вывода списка строк позволяет тривиально изменять каждую строку, возникающую в результате рекурсивного вызова. – Carl

ответ

2

Вы можете использовать аккумулятор (здесь, depth), чтобы отслеживать, насколько глубоко вы в настоящее время находитесь в дереве - затем создайте несколько пробелов, соответствующих глубине линии, по адресу:

main = putStrLn $ printTree tree 
data Tree = Empty | Node Int (Tree) (Tree) deriving (Show) 
tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty 

printTree :: Tree -> String 
printTree x = printTree' x 0 
    where 
    printTree' x depth = case x of 
     Node num treeA treeB -> (replicate (2 * depth) ' ') ++ show num ++ "\n" ++ (printTree' treeA (depth + 1)) ++ "\n" ++ (printTree' treeB (depth + 1)) 
     Empty -> (replicate (2 * depth) ' ') ++ "Empty" 

Выход:

*Main> main 
4 
    3 
    Empty 
    2 
     Empty 
     Empty 
    Empty 
0

Хорошо, я думаю, что я получил его на работу.

printTree :: Tree -> String                                              
printTree x = printT 0 x                                                     

space x = take x $ cycle " "                                              

printT :: Int -> Tree -> String                                             
printT num x =                                                 
    case x of                                                  
    (Node o treeA treeB) -> show o ++                                           
          "\n" ++                                            
          space num ++                                           
          printT (num+1) treeA ++                                        
          "\n" ++                                            
          space num ++                                           
          printT (num+1) treeB                                         
    Empty -> "Empty" 
1

Вот решение с использованием -XImplicitParams в GHC

{-# LANGUAGE ImplicitParams #-} 
module ImplicitTabs where 

data Tree = Empty | Node Int (Tree) (Tree) deriving (Show) 
tree = Node 4 (Node 3 Empty (Node 2 Empty Empty)) Empty           

tab :: (?tab_level :: Int) => String 
tab = replicate (2 * ?tab_level) ' ' 

printTree :: (?tab_level :: Int) => Tree -> String 
printTree x = let 
    ?tab_level = ?tab_level + 1 
    in case x of 
    Node num treeA treeB -> tab ++ show num ++ "\n" ++ tab ++ printTree treeA ++ "\n" ++ tab ++ printTree treeB 
    Empty -> tab ++ "Empty" 

main = let ?tab_level = -1 in putStrLn $ printTree tree 


> runhaskell implicit-tabulation.hs 
4 
    3 
     Empty 
     2 
      Empty 
      Empty 
    Empty 
+1

IMO 'ImplicitParams' здесь полностью переполнен. Регулярный параметр был бы прекрасен ... – luqui

0

Если преобразовать в Data.Tree, то вы можете использовать функцию drawTree библиотеки, которая делает почти то, что вы ищете (это также привлекает ветви с изображением ASCII).

Смежные вопросы