簡體   English   中英

具有復雜類型的 Swift CustomStringConvertible

[英]Swift CustomStringConvertible with complex type

我希望 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{ 打印 ($0.description)}}

但是,我無法通過節點的描述來實現 in。

我試圖為每個語句寫出相當於我的

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

但在這種情況下,執行會給出 EXC_BAD_ACCESS,實際上我無法獲得任何代碼來完成並給出節點和其中包含的邊的描述。

如何完成節點的描述字符串,然后繼續描述邊緣?

似乎您的description代碼會導致Node.descriptionEdge.description無限Edge.description

Node為每條邊調用Edge.description ,而Edge為其來自和到節點調用Node.description 如果圖形是圓形連接,而不是星形連接,則會導致無限循環。

一個簡單的方法是Edge.description只顯示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成員,如果可以的話),並盡量不要訪問那些訪問過的節點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM