代码之家  ›  专栏  ›  技术社区  ›  stevenpcurtis

复杂类型的Swift CustomStrings敞篷车

  •  1
  • stevenpcurtis  · 技术社区  · 7 年前

    我希望CustomStringConvertible为我提供节点的描述,特别是它包含的边。

    作为背景,我一直在研究图论,并创建了一个节点:

    class Node : CustomStringConvertible {
        // unique identifier required for each node
        var identifier : Int
        var distance : Int = Int.max
        var edges = [Edge]()
        var visited = false
    
        var description: String {
            return "identifier: " + identifier.description + ", Edges: " + ( "edgesString" )
        }
    
        init(visited: Bool, identifier: Int, edges: [Edge]) {
            self.visited = visited
            self.identifier = identifier
            self.edges = edges
        }
    
        static func == (lhs: Node, rhs: Node) -> Bool {
            return lhs.identifier == rhs.identifier
        }
    }
    

    有棱角

    class Edge {
        var from: Node // does not actually need to be stored!
        var to: Node
        var weight: Int
        var description : String {
            return "from: " + from.description + ", to: " + to.description + ", weight: " + weight.description
        }
        init(to: Node, from: Node, weight: Int) {
            self.to = to
            self.weight = weight
            self.from = from
        }
    }
    

    我可以很容易地打印出每个节点的每个边

    testGraph.nodes.forEach{$0.edges.forEach{print($0.description)}

    我试着为每一个语句写下与我的相同的内容

    var description: String {
        var edgesString = String()
        edges.forEach{  edgesString.append($0.description)}
        return "identifier: " + identifier.description + ", Edges: " + ( edgesString )
    }
    

    但是执行提供了一个EXC_BAD_访问在这种情况下,事实上我无法得到任何代码来完成,并给我节点和其中包含的边的描述。

    如何完成节点的描述字符串,然后继续描述边?

    1 回复  |  直到 7 年前
        1
  •  1
  •   taka    7 年前

    看来你的 description Node.description Edge.description .

    Node 呼叫 边缘描述 对于每个边,以及 Edge 呼叫 Node.description 用于其“从”和“到”节点。如果图具有圆形连接,而不是星形连接,则会导致无限roop。

    一个简单的方法是 唯一显示 Node.identifier 而不是详细的描述。

    class Edge {
        var from: Node // does not actually need to be stored!
        var to: Node
        var weight: Int
        var description : String {
            return "{ Edge, from: \(from.identifier), to: \(to.identifier), weight: \(weight) }"
        }
        init(to: Node, from: Node, weight: Int) {
            self.to = to
            self.weight = weight
            self.from = from
        }
    }
    class Node : CustomStringConvertible {
        // unique identifier required for each node
        var identifier : Int
        var distance : Int = Int.max
        var edges = [Edge]()
        var visited = false
    
        var description: String {
            let edgesString = edges.map { $0.description }.joined(separator: ", ")
            return "{ Node, identifier: \(identifier), Edges: [\(edgesString)] }"
        }
    
        init(visited: Bool, identifier: Int, edges: [Edge]) {
            self.visited = visited
            self.identifier = identifier
            self.edges = edges
        }
    
        static func == (lhs: Node, rhs: Node) -> Bool {
            return lhs.identifier == rhs.identifier
        }
    }
    
    let rootNode = Node(visited: false, identifier: 10, edges: [])
    var edges: [Edge] = []
    for i in 0..<3 {
        let node = Node(visited: false, identifier: i, edges: [])
        let edge = Edge(to: node, from: rootNode, weight: i)
        edges.append(edge)
    }
    rootNode.edges = edges
    
    print(rootNode)
    // { Node, identifier: 10, Edges: [{ Edge, from: 10, to: 0, weight: 0 }, { Edge, from: 10, to: 1, weight: 1 }, { Edge, from: 10, to: 2, weight: 2 }] }
    

    visited 成员),并尝试不访问那些已访问的节点。