Swift:如何在不使用连接或更高阶函数的情况下逐级打印树?

时间:2018-04-17 17:41:48

标签: swift string algorithm loops data-structures

树类

class TreeNode<T>{
    weak var parent: TreeNode?
    var children: [TreeNode] = []

    var value: T

    init(value: T){
        self.value = value
    }

    func add(_ child: TreeNode){
        self.children.append(child)
        print(children)
        child.parent = self
    }  
}

打印树

extension TreeNode{        

    func printTree() -> String{
        var returnString = "\(value)"
        if children.isEmpty == false{
            returnString = "{" + returnString + "{"
            for child in children{
                print("child count: \(children.count)")
                print("before: \(returnString)")
                returnString = returnString + "," + child.printTree()
            }
        returnString = returnString + "}"
        }
        if children.isEmpty == false{
            returnString += "}"
        }

        return returnString
    }
}

问题示例

let world = TreeNode(value: "World")
let america = TreeNode(value: "America")
let asia = TreeNode(value: "Asia")
let northAmerica = TreeNode(value: "North America")
let southAmerica = TreeNode(value: "South America")

world.add(america)
america.add(northAmerica)
america.add(southAmerica)

print(world.printTree())
  

{World {,{America {,North America,South America}}}}

问题

,{是不必要的。但它需要在两个元素之间。我正在考虑通过了解索引将其从第一个元素中删除,但不要认为这是一个非常好的解决方案。还有其他选择吗?

我知道我可以做类似的事情:

extension TreeNode: CustomStringConvertible {
  public var description: String {
    var s = "\(value)"
    if !children.isEmpty {
      s += " {" + children.map { $0.description }.joined(separator: ", ") + "}"
    }
    return s
  }
}

☝️RW

但我不想使用高阶函数,也不想使用.joined

2 个答案:

答案 0 :(得分:1)

extension TreeNode: CustomStringConvertible {

    var description: String {
        if children.isEmpty { return "\(value)" }
        var string = "{\(value){"
        var separator = ""
        for child in children {
            string += separator
            separator = ","
            string += child.description
        }
        string += "}}"
        return string
    }

}

答案 1 :(得分:0)

我的解决方案有点罗嗦:)我用自己的两种方法替换了printTree

func describeNode() -> String  {
    var string: String
    switch children.count{
        case 0: string = ""
        case 1: 
            let child = children[0] 
            string = "{\(extractNode(child, andAppend: "}"))"
        default: 
         string = "{"
        let max = children.count - 1
        for i in 0..<max {
            let child = children[i]
            string.append(extractNode(child, andAppend: ","))
        }
        string.append("\(children[max].value)}")
    }
    return "\(string)"
}

private func extractNode(_ node: TreeNode, andAppend suffix: String) -> String {
    var string = "\(node.value)"
    if !node.children.isEmpty {
        string.append(node.describeNode())
    }
    string.append(suffix)
    return string
}

我使用了以下测试用例

let world = TreeNode(value: "World")
let america = TreeNode(value: "America")
let northAmerica = TreeNode(value: "North America")
let southAmerica = TreeNode(value: "South America")

world.add(america)
america.add(northAmerica)
america.add(southAmerica)
america.add(TreeNode(value: "Central America"))
northAmerica.add(TreeNode(value: "Canada"))
northAmerica.add(TreeNode(value: "USA"))

print(world.describeNode())

打印 {America {North America {Canada,USA},South America,Central America}}