diff --git a/Encode and Decode Tree/EncodeAndDecodeTree.playground/Contents.swift b/Encode and Decode Tree/EncodeAndDecodeTree.playground/Contents.swift index dbd2fd180..44c2440d5 100644 --- a/Encode and Decode Tree/EncodeAndDecodeTree.playground/Contents.swift +++ b/Encode and Decode Tree/EncodeAndDecodeTree.playground/Contents.swift @@ -1,13 +1,10 @@ //: Playground - noun: a place where people can play - -func printTree(_ root: TreeNode?) { +func printTree(_ root: BinaryNode?) { guard let root = root else { return } - var pointer = root - let leftVal = root.left == nil ? "nil" : root.left!.val let rightVal = root.right == nil ? "nil" : root.right!.val @@ -17,25 +14,25 @@ func printTree(_ root: TreeNode?) { printTree(root.right) } -let s = EncodeAndDecodeTree() +let coder = BinaryNodeCoder() -let node1 = TreeNode("a") -let node2 = TreeNode("b") -let node3 = TreeNode("c") -let node4 = TreeNode("d") -let node5 = TreeNode("e") +let node1 = BinaryNode("a") +let node2 = BinaryNode("b") +let node3 = BinaryNode("c") +let node4 = BinaryNode("d") +let node5 = BinaryNode("e") node1.left = node2 node1.right = node3 node3.left = node4 node3.right = node5 -let encodeStr = s.encode(node1) +let encodeStr = try coder.encode(node1) print(encodeStr) // "a b # # c d # # e # #" -let root = s.decode(encodeStr) +let root: BinaryNode = coder.decode(from: encodeStr)! print("Tree:") printTree(root) /* diff --git a/Encode and Decode Tree/EncodeAndDecodeTree.playground/Sources/EncodeAndDecodeTree.swift b/Encode and Decode Tree/EncodeAndDecodeTree.playground/Sources/EncodeAndDecodeTree.swift index e9d22f8a9..10bb277f5 100644 --- a/Encode and Decode Tree/EncodeAndDecodeTree.playground/Sources/EncodeAndDecodeTree.swift +++ b/Encode and Decode Tree/EncodeAndDecodeTree.playground/Sources/EncodeAndDecodeTree.swift @@ -8,97 +8,88 @@ import Foundation -public class TreeNode { - public var val: String - public var left: TreeNode? - public var right: TreeNode? - - public init(_ val: String, left: TreeNode? = nil, right: TreeNode? = nil) { - self.val = val - self.left = left - self.right = right - } +protocol BinaryNodeEncoder { + func encode(_ node: BinaryNode?) throws -> String } -public class EncodeAndDecodeTree { - private var encodeStr = "" - private var ret: [String] = [] +protocol BinaryNodeDecoder { + func decode(from string: String) -> BinaryNode? +} - public init() {} +public class BinaryNodeCoder: BinaryNodeEncoder, BinaryNodeDecoder { - public func encode(_ root: TreeNode?) -> String { - encodeIt(root) + // MARK: Private - return encodeStr - } + private let separator: Character = "," + private let nilNode = "X" - public func decode(_ data: String) -> TreeNode? { - var s = data - while (s.contains(" ")) { - let index = s.index(of: " ") - let endIndex = s.index(before: index) - let element = s[s.startIndex...endIndex] - ret.append(element) - let range = ClosedRange(uncheckedBounds: (lower: s.startIndex, upper: index)) - s.removeSubrange(range) - } - - if ret.count == 0 { - return nil - } - - var dep = 0 - let root = decodeIt(&dep) - - return root + private func decode(from array: inout [String]) -> BinaryNode? { + guard !array.isEmpty else { + return nil } - private func getNode(_ element: String) -> TreeNode? { - if element == "#" { - return nil - } + let value = array.removeLast() - return TreeNode(element) + guard value != nilNode, let val = value as? T else { + return nil } - private func decodeIt(_ dep: inout Int) -> TreeNode? { - guard let currentNode = getNode(ret[dep]) else { - return nil - } + let node = BinaryNode(val) + node.left = decode(from: &array) + node.right = decode(from: &array) - dep += 1 - let left = decodeIt(&dep) - dep += 1 - let right = decodeIt(&dep) + return node + } - currentNode.left = left - currentNode.right = right + // MARK: Public - return currentNode + public init() {} + + public func encode(_ node: BinaryNode?) throws -> String { + var str = "" + node?.preOrderTraversal { data in + if let data = data { + let string = String(describing: data) + str.append(string) + } else { + str.append(nilNode) + } + str.append(separator) } - private func encodeIt(_ root: TreeNode?) { - guard let root = root else { - encodeStr += "# " - return - } + return str + } - encodeStr += root.val + " " - encodeIt(root.left) - encodeIt(root.right) - } + public func decode(from string: String) -> BinaryNode? { + var components = string.split(separator: separator).reversed().map(String.init) + return decode(from: &components) + } } -extension String { - func index(of target: Character) -> String.Index { - var i = 0 - for c in self.characters { - if c == target { - return self.index(self.startIndex, offsetBy: i) - } - i += 1 - } - - return self.endIndex +public class BinaryNode { + public var val: Element + public var left: BinaryNode? + public var right: BinaryNode? + + public init(_ val: Element, left: BinaryNode? = nil, right: BinaryNode? = nil) { + self.val = val + self.left = left + self.right = right + } + + public func preOrderTraversal(visit: (Element?) throws -> ()) rethrows { + try visit(val) + + if let left = left { + try left.preOrderTraversal(visit: visit) + } else { + try visit(nil) + } + + if let right = right { + try right.preOrderTraversal(visit: visit) + } else { + try visit(nil) } + } } diff --git a/Encode and Decode Tree/EncodeAndDecodeTree.swift b/Encode and Decode Tree/EncodeAndDecodeTree.swift index daa3c3ea2..6ec8a3046 100644 --- a/Encode and Decode Tree/EncodeAndDecodeTree.swift +++ b/Encode and Decode Tree/EncodeAndDecodeTree.swift @@ -8,97 +8,88 @@ import Foundation -public class TreeNode { - public var val: String - public var left: TreeNode? - public var right: TreeNode? - - public init(_ val: String, left: TreeNode? = nil, right: TreeNode? = nil) { - self.val = val - self.left = left - self.right = right - } +protocol BinaryNodeEncoder { + func encode(_ node: BinaryNode?) throws -> String } -public class EncodeAndDecodeTree { - private var encodeStr = "" - private var ret: [String] = [] +protocol BinaryNodeDecoder { + func decode(from string: String) -> BinaryNode? +} - public init() {} +public class BinaryNodeCoder: BinaryNodeEncoder, BinaryNodeDecoder { - public func encode(_ root: TreeNode?) -> String { - encodeIt(root) + // MARK: Private - return encodeStr - } + private let separator: Character = "," + private let nilNode = "X" - public func decode(_ data: String) -> TreeNode? { - var s = data - while (s.contains(" ")) { - let index = s.index(of: " ") - let endIndex = s.index(before: index) - let element = s[s.startIndex...endIndex] - ret.append(element) - let range = ClosedRange(uncheckedBounds: (lower: s.startIndex, upper: index)) - s.removeSubrange(range) - } - - if ret.count == 0 { - return nil - } - - var dep = 0 - let root = decodeIt(&dep) - - return root + private func decode(from array: inout [String]) -> BinaryNode? { + guard !array.isEmpty else { + return nil } - private func getNode(_ element: String) -> TreeNode? { - if element == "#" { - return nil - } + let value = array.removeLast() - return TreeNode(element) + guard value != nilNode, let val = value as? T else { + return nil } - private func decodeIt(_ dep: inout Int) -> TreeNode? { - guard let currentNode = getNode(ret[dep]) else { - return nil - } + let node = BinaryNode(val) + node.left = decode(from: &array) + node.right = decode(from: &array) - dep += 1 - let left = decodeIt(&dep) - dep += 1 - let right = decodeIt(&dep) + return node + } - currentNode.left = left - currentNode.right = right + // MARK: Public - return currentNode + public init() {} + + public func encode(_ node: BinaryNode?) throws -> String { + var str = "" + node?.preOrderTraversal { data in + if let data = data { + let string = String(describing: data) + str.append(string) + } else { + str.append(nilNode) + } + str.append(separator) } - private func encodeIt(_ root: TreeNode?) { - guard let root = root else { - encodeStr += "# " - return - } + return str + } - encodeStr += root.val + " " - encodeIt(root.left) - encodeIt(root.right) - } + public func decode(from string: String) -> BinaryNode? { + var components = string.split(separator: separator).reversed().map(String.init) + return decode(from: &components) + } } -extension String { - func index(of target: Character) -> String.Index { - var i = 0 - for c in self.characters { - if c == target { - return self.index(self.startIndex, offsetBy: i) - } - i += 1 - } - - return self.endIndex +public class BinaryNode { + public var val: Element + public var left: BinaryNode? + public var right: BinaryNode? + + public init(_ val: Element, left: BinaryNode? = nil, right: BinaryNode? = nil) { + self.val = val + self.left = left + self.right = right + } + + public func preOrderTraversal(visit: (Element?) throws -> ()) rethrows { + try visit(val) + + if let left = left { + try left.preOrderTraversal(visit: visit) + } else { + try visit(nil) + } + + if let right = right { + try right.preOrderTraversal(visit: visit) + } else { + try visit(nil) } + } }