-1

create a Trie from an array of strings using in swift

The concept is : you have given an array of strings like :

# The input will be always in the below format "x1>x2>x3...>xn=Integer" else it is invalid input #

private let input = [
    "a>b>c=1",
    "a>b>c=2",
    "d>c=3",
    "f>e=10",
    "a>b=20",  // Invalid, Node(b) has Child, cannot insert the value
    "a>b>c>d=11", // Invalid , Node(c) has value, but trying to insert child, invalid case
    "a>a>a=100"
]

(1). Let's consider the first input : "a>b>c=1" which consists of 2 parts based on "=" operator "a>b>c" and "1".

The first part is used for tree hierarchy where x>y means x is parent of y and the value "1" will be child of last node. It creates a tree like below for the first time as tree is empty at beginning.

( Root ) --> ("a") --> ("b") --> ("c") --> [1]

(2) Consider 2nd input : "a>b>c=2". Divide the input into 2 parts "a>b>c" and "2" based on "=". While processing "a>b>c", it's simply traversing because node("a"), node("b"), node("c") are in correct hierarchy and update the value node by appending value=2 so value([1,2]). Tree looks like :

( Root ) --> ("a") --> ("b") --> ("c") --> [1,2]

(3) Considering "d>c=3", the tree looks like :

( Root ) --> ("a") --> ("b") --> ("c") --> [1,2]
   |
   --> ("d") --> ("c") --> [3]

(4) Considering "a>b=20" input produce an ERROR because node("b") has a child node("c") so you cannot insert value([20]) for node("b"), So, don't process for this input. (no modification in tree)

(5) considering "a>b>c>d=11" input, produce an ERROR because node("c") has a Value([1,2]) child, you cannot add a node("d") as child of node("c"), So, don't process for this input. (no modification in tree)

You have to construct the Trie like below considering the above input.

 {
        "a" : { "b" : { "c" : [1,2] },
                "a" : { "a" : [100] }
              },
        "d" : { "c" : [3]  },
        "f" : { "e" : [10] }
 }
Ashis Laha
  • 2,176
  • 3
  • 16
  • 17

1 Answers1

-1

Solution :

import Foundation

// Element must have either value or childDictionary, not at the same time

class Element {
  var value : [Int]?
  var childDictionary : Dictionary<String, Element>?

  init(value : [Int]?, childKey : String?, childValue : Element? ) {
     self.value = value
     self.childDictionary = nil

     if let childKey = childKey, let childValue = childValue {
         var dict = Dictionary<String, Element>()
         dict[childKey] = childValue
         childDictionary = dict
     }
  }
}

class JsonCreator {

private var root : Element?

private let jsonInput = [
    "a>b>c=1",
    "a>b>c=2",
    "d>c=3",
    "f>e=10",
    "a>b=20",  // Invalid, Node(b) has Child, cannot insert the value
    "a>b>c>d=11" // Invalid , Node(c) has value, but trying to insert child, invalid case
]

public func create() {
    root = Element(value: nil, childKey: nil, childValue: nil) // root one
    createJSON(input: jsonInput)
    print("\n\n Output \n\n")
    printJson(root: root)
}

private func createJSON(input : [String]) {

    let rootJson = root

    for each in input {
        print("\n---------------------- New Input ----------------------\n")
        // split the string into 2 parts
        let parts = each.components(separatedBy: "=")

        if parts.count > 1 { // go through the hierarchy

            let literals = parts[0].filter{ $0 != ">" }
            print(literals)

            var traversal = rootJson
            var char : Character!
            var hasError = false

            // literals
            for i in 0..<literals.count {
                char = literals[literals.index(literals.startIndex, offsetBy: i)]
                print("Processing : \(char!)")

                if let _ = traversal?.value {
                    print("ERROR : Node has value, but trying to insert child, invalid case")
                    hasError = true
                    break

                } else if traversal?.childDictionary == nil {
                    print("Child is Empty : Do Insertion")
                    let node = Element(value: nil, childKey:nil , childValue: nil)
                    var dict = Dictionary<String, Element>()
                    dict[String(char)] = node
                    traversal?.childDictionary = dict
                    traversal = node // update traversal

                } else if let isChildPresent = traversal?.childDictionary?.keys.contains(String(char)), !isChildPresent {
                    print("Child is not Empty, but not present in the hierary, Do Insertion")
                    let node = Element(value: nil, childKey:nil , childValue: nil)
                    traversal?.childDictionary?[String(char)] = node
                    traversal = node // update traversal

                } else {
                    print("Child is not Empty, but present in the hierary: NO Insertion, only traverse ")
                    if let updateTraversal =  traversal?.childDictionary?[String(char)] {
                        traversal = updateTraversal // update traversal
                    }
                }
            }

            // Value
            if let _ = char, let val = Int(parts[1]), !hasError {
                print("value : \(val)")

                if let _ = traversal?.childDictionary {
                    print("ERROR : Node has Child, cannot insert the value")
                } else {
                    print("Append the value")
                    if let _ = traversal?.value {
                        traversal?.value?.append(val)
                    } else {
                        traversal?.value = [val]
                    }
                }
            }
            root = rootJson // update root for every input
        }
    }
}

private func printJson(root : Element?) {
    if let childDictionary = root?.childDictionary {
        for each in childDictionary {
            print("{ \(each.key) : ", terminator : "")
            printJson(root: each.value)
            print("}")
        }
    }

    if let values = root?.value {
        print("\(values)")
    }
 }
}

let jsonCreateObj = JsonCreator()
jsonCreateObj.create()

Output :

     ---------------------- New Input ----------------------

     abc
     Processing : a
     Child is Empty : Do Insertion
     Processing : b
     Child is Empty : Do Insertion
     Processing : c
     Child is Empty : Do Insertion
     value : 1
     Append the value

     ---------------------- New Input ----------------------

     abc
     Processing : a
     Child is not Empty, but present in the hierary: NO Insertion, only traverse 
     Processing : b
     Child is not Empty, but present in the hierary: NO Insertion, only traverse 
     Processing : c
     Child is not Empty, but present in the hierary: NO Insertion, only traverse 
     value : 2
     Append the value

    ---------------------- New Input ----------------------

    dc
    Processing : d
    Child is not Empty, but not present in the hierary, Do Insertion
    Processing : c
    Child is Empty : Do Insertion
    value : 3
    Append the value

    ---------------------- New Input ----------------------

    fe
    Processing : f
    Child is not Empty, but not present in the hierary, Do Insertion
    Processing : e
    Child is Empty : Do Insertion
    value : 10
    Append the value

    ---------------------- New Input ----------------------

    ab
    Processing : a
    Child is not Empty, but present in the hierary: NO Insertion, only traverse 
    Processing : b
    Child is not Empty, but present in the hierary: NO Insertion, only traverse 
   value : 20
   ERROR : Node has Child, cannot insert the value

   ---------------------- New Input ----------------------

   abcd
   Processing : a
   Child is not Empty, but present in the hierary: NO Insertion, only traverse 

   Processing : b
   Child is not Empty, but present in the hierary: NO Insertion, only traverse 

   Processing : c
   Child is not Empty, but present in the hierary: NO Insertion, only traverse 

   Processing : d
   ERROR : Node has value, but trying to insert child, invalid case


   Output 


   { d : { c : [3]
   }
   }
   { a : { b : { c : [1, 2]
   }
   }
   }
   { f : { e : [10]
   }
   }
Ashis Laha
  • 2,176
  • 3
  • 16
  • 17