data class Node(val ID : Long, val name : String)
我有以下三个值的有序列表(按出现顺序):ID,名称和深度。
0000 : A : 0
0001 : B : 1
0002 : C : 2
0003 : D : 2
0004 : E : 1
0005 : F : 2
0006 : G : 1
0007 : H : 1
0008 : I : 2
使用此数据集我希望将原始 N -ary树重建为Map<Node, Set<Node>>
,可视化如下:
A - B - C
- D
- E - F
- G
- H - I
完成此任务的最佳(最高效和/或最可读)方法是什么?
答案 0 :(得分:2)
给定orderedList: List<Triple<Long, String, Int>>
,您可以遍历三元组并跟踪每个深度的当前父级,以便您可以重建树:
val tree = mutableMapOf<Node, MutableSet<Node>>()
val parents = ArrayDeque<Node>()
for ((id, name, depth) in orderedList) {
val node = Node(id, name)
// pop any parents from this deque as deep or deeper than this node
while (parents.size > depth) parents.pop()
// add node to tree
tree[node] = mutableSetOf()
// add node to parent's children if applicable
tree[parents.peek()]?.add(node)
// add node to parents stack
parents.push(node)
}
如果您需要从字符串中构建orderedList
,您可以使用以下内容(假设字符串可用作input: String
):
val orderedList = input.trim().lines().map { line ->
val components = line.split(" : ")
val id = components.component1().toLong()
val name = components.component2()
val depth = components.component3().toInt()
Triple(id, name, depth)
}
答案 1 :(得分:1)
基本思想是使用堆栈跟踪从根到当前处理的节点的轨道上的父节点:
val input = """
0000 : A : 0
0001 : B : 1
0002 : C : 2
0003 : D : 2
0004 : E : 1
0005 : F : 2
0006 : G : 1
0007 : H : 1
0008 : I : 2
"""
val parsedLines = input.split("\n")
.map { it.trim() }
.filter { it.isNotEmpty() }
.map { line ->
val parsedLine = line
.split(":")
.map { it.trim() }
object {
val preOrderIndex = parsedLine[0].toInt()
val name = parsedLine[1]
val height = parsedLine[2].toInt()
}
}
.sortedBy { it.preOrderIndex }
parsedLines.forEach { println("${it.preOrderIndex} ${it.name} ${it.height}") }
val map = HashMap<Node,HashSet<Node>>()
val parents = Stack<Node>()
for (nodeDesc in parsedLines) {
val newNode = Node(nodeDesc.preOrderIndex.toLong(), nodeDesc.name)
map[newNode] = HashSet<Node>()
while (parents.size > nodeDesc.height)
parents.pop()
if (!parents.empty()) {
val tmp: HashSet<Node>? = map[parents.peek()]
tmp!!.add(newNode)
}
parents.push(newNode)
}
println(map)