Advertisement
Guest User

Untitled

a guest
Oct 30th, 2017
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.96 KB | None | 0 0
  1. open System;
  2.  
  3. type Tree =
  4.     | Leaf of string
  5.     | InternalTree of string * Tree list
  6.  
  7. let createTree =
  8.     let rec createInnerTrees node =
  9.         let innerTreesNodes =
  10.             Seq.initInfinite (fun id ->
  11.                 printf "Введите %A-й узел родительского узла %A (-1 для прекращения):\n" id node;
  12.                 Console.ReadLine())
  13.             |> Seq.takeWhile (fun x -> x <> "-1")
  14.             |> Seq.toList;
  15.  
  16.         let innerTrees =
  17.             innerTreesNodes
  18.                 |> Seq.map (fun node ->
  19.                     let nodeInnerTrees = createInnerTrees node;
  20.                     match List.length nodeInnerTrees with
  21.                         | 0 -> Leaf node
  22.                         | _ -> InternalTree (node, nodeInnerTrees))
  23.                 |> Seq.toList;
  24.  
  25.         innerTrees
  26.  
  27.     printf "Введите корень дерева:\n"
  28.     let root = Console.ReadLine();
  29.  
  30.     InternalTree (root, createInnerTrees root)
  31.  
  32. let rec isBinary (tree:Tree) =
  33.     match tree with
  34.         | Leaf _ -> true
  35.         | InternalTree (_, innerTrees) ->
  36.             (innerTrees.Length <= 2) && (innerTrees |> Seq.forall (fun innerTree -> isBinary innerTree))
  37.  
  38. let drawBinaryTree (tree:Tree) =
  39.     let rec getOutputElements node x y=
  40.         match node with
  41.             | Leaf n -> [(n, x, y)]
  42.             | InternalTree (n,innerTrees) ->
  43.                 let childElements = match innerTrees.Length with
  44.                     | 1 ->
  45.                         [("/",x-1,y+1)] @
  46.                         [("/",x-2,y+2)] @
  47.                         (getOutputElements (innerTrees.Item(0)) (x-3) (y+3))
  48.                     | 2 ->
  49.                         [("/",x-1,y+1)] @
  50.                         [("/",x-2,y+2)] @
  51.                         (getOutputElements (innerTrees.Item(0)) (x-3) (y+3)) @
  52.                         [("\\",x+1,y+1)] @
  53.                         [("\\",x+2,y+2)] @
  54.                         (getOutputElements (innerTrees.Item(1)) (x+3) (y+3))
  55.  
  56.                 [(n, x, y)] @ childElements
  57.        
  58.     let drawLine elements =
  59.         let maxX =
  60.             elements
  61.             |> Seq.map (fun (_,x,_) -> x)
  62.             |> Seq.max;
  63.  
  64.         let drawElement curX elements =
  65.             let el = elements |> Seq.tryFind (fun (_,x,_) -> x = curX);
  66.             if (el.IsSome) then
  67.                 printf "%s" (match el.Value with (s,_,_) -> s);
  68.             else
  69.                 printf " "
  70.             ()
  71.  
  72.         [0..maxX] |> Seq.iter (fun curX -> drawElement curX elements)
  73.         printf "\n"
  74.         ()
  75.  
  76.     let outputElements = getOutputElements tree 40 0
  77.    
  78.     let groups =
  79.         outputElements
  80.         |> Seq.groupBy (fun (_, _, y) -> y)
  81.         |> Seq.sortBy (fun (key, value) -> key)
  82.         |> Seq.iter (fun (key, value) -> drawLine value)
  83.  
  84.     ()
  85.  
  86. let printRegularTree (tree:Tree) =
  87.     let rec printElement node  spaces =
  88.         printf "%s" spaces;
  89.         match node with
  90.         | Leaf n ->
  91.             printf "Лист: %s\n" n
  92.         | InternalTree (n, innerTrees) ->
  93.             printf "Узел: %s\n" n
  94.             for node in innerTrees do printElement node (spaces + "   ")
  95.  
  96.     printElement tree "";
  97.  
  98. let printTree (tree:Tree) =
  99.     if (isBinary tree) then
  100.         drawBinaryTree tree
  101.     else
  102.         printRegularTree tree
  103.  
  104. let rec findElement (tree:Tree) el =
  105.     match tree with
  106.     | Leaf n -> n = el
  107.     | InternalTree (n,innerTrees) ->
  108.         (n = el) || (innerTrees |> Seq.exists (fun tree -> findElement tree el))
  109.  
  110. [<EntryPoint>]
  111. let main argv =
  112.  
  113.     let tree = createTree;
  114.  
  115.     printTree tree;
  116.  
  117.     printf "Введите элемент, который надо найти\n";
  118.     let node = Console.ReadLine();
  119.  
  120.     if (findElement tree node) then
  121.         printf "Элемент %A найден\n" node
  122.     else
  123.         printf "Элемента %A нет в дереве\n" node
  124.  
  125.     Console.ReadLine() |> ignore;
  126.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement