给出以下CSV,它表示一般化层次结构(想想:邮政编码匿名化,例如在第二步中,邮政编码 46072 变为 460 ** ):< / p>
A1, A*, *
A2, A*, *
A3, A*, *
B1, B*, *
B2, B*, *
B3, B*, *
B4, B*, *
我首先解析它来创建一个数组数组。
我现在想把它变成树形表示:
*
/ \
A* B*
/ | \ / | | \
A1 A2 A3 B1 B2 B3 B4
正如您所看到的那样,每个节点都有一个任意数量的子节点。
我有以下课程:
表, TableRow , TableCell 以及树和节点。 显然,一个表有多行,而这些行又有多个单元格。 树具有根节点,节点具有各种操作,例如 addChild(节点), getParent(), getChildren()等< / p>
我正在试图找出,如何迭代我的桌子,以便跨越如上图所示的树。到目前为止,我只是让自己陷入混乱......
非常感谢帮助!
答案 0 :(得分:1)
行。所以,我的答案基于这些假设:
我不确切知道你的类Table,Tree和Node能做什么或不能做什么。所以我使用了一个基础2d数组(你也说过解析之后的数据),并且只使用了一个基本的节点作为我的树结构。
这个想法是从头部矩阵递归地工作。递归和树一起很好......
树被定义为将最右边的列中的值作为其根值,并且通过消除最右边的列,并将矩阵切割成片段使得它们的子节点以相同的方式创建。最右边的列具有相同的值。矩阵
A1, A*, *
A2, A*, *
A3, A*, *
B1, B*, *
B2, B*, *
B3, B*, *
B4, B*, *
被分成一个值&#34; *&#34;和两个子矩阵:
A1, A*
A2, A*
A3, A*
B1, B*
B2, B*
B3, B*
B4, B*
A*
矩阵也是如此,其子矩阵是单细胞矩阵A1
,A2
和A3
,此时递归结束。
因此,假设您创建了一个表示层次结构构建器的类,并且您有一个名为data
的2D数组,那么您将拥有一个不带参数的公共方法,它可以调用&#34;脏&#34;私有方法,其参数表示当前子矩阵的矩阵边界。
public Node<String> createTree() {
return this.createTree(0,data.length-1,data[0].length-1);
}
它传递给私有方法的参数是顶行,底行,最左列和最右列。只有在这种情况下,子矩阵始终从第0列开始,我们不需要将最左边的列作为参数传递。
这是您的私人createTree
方法:
private Node<String> createTree( int firstRow, int lastRow, int lastCol) {
// Recursion end. If we are at the leftmost column, just return a simple
// node with the value at the current row and column.
if ( lastCol == 0 ) {
return new Node<String>( data[firstRow][0] );
}
// Create a node with the value of the top-right cell in our range.
Node<String> result = new Node<String>(data[firstRow][lastCol]);
// The next column from the right will have the values for the child nodes.
// Split it into ranges (start row -> end row) and recursively build
// the tree over the sub-matrix that goes column 0 -> lastCol-1 over each
// range of rows.
int childFirstRow = firstRow;
String childVal = data[firstRow][lastCol-1];
for( int candidateRow = firstRow; candidateRow <= lastRow; candidateRow ++ ) {
// If the next value in the column is different from what we had so far, it's
// the end of a row range, build the child tree, and mark this row as
// the beginning of the next range.
if ( ! data[candidateRow][lastCol-1].equals(childVal) ) {
result.addChild(createTree( childFirstRow, candidateRow - 1, lastCol - 1));
childFirstRow = candidateRow;
childVal = data[childFirstRow][lastCol-1];
}
// In the special case of the last row, it's always the end of a range.
if ( candidateRow == lastRow ) {
result.addChild(createTree(childFirstRow,lastRow,lastCol - 1));
}
}
return result;
}