我正在努力将分隔文件转换为有序树结构。以下是输入示例...
1.2.3.4.5
1.3.2.4.5
1.2.4.5.6
我需要能够将其转换为如下所示的输出(在可搜索的树结构中)...
1
-2
--3
---4
----5
--4
---5
----6
-3
--2
---4
----5
我对此解决方案的想法是......
我认为一切都运行良好但是当我开始测试这种方法时,我发现我的输出看起来如下......
1
-2
--3
---4
----5
--4
---5
----6
-3
--2
可以看出,3/2 / xx下的节点不存在,这是由于我用来为我的Node值构建LinkedHashSet的逻辑(Node(3,4))将被忽略,因为它是一个重复的节点。我以为我正朝着正确的方向前进,但现在我可以看出我的逻辑显然存在缺陷。有没有人对这样的方法有任何建议?我目前的代码低于......
TreeBuilder.java
public class TreeBuilder {
public static void main(String[] args) {
// Get a list of records
List<String> data = new ArrayList<String>();
data.add("1.2.3.4.5");
data.add("1.3.2.4.5");
data.add("1.2.4.5.6");
Collections.sort(data);
// Build the "Base" tree
TreeMap<String, List<String>> tree = buildBaseTree(data);
// Build the target tree structure
TreeMap<String, LinkedHashSet<Node>> finalTree = convertListToSet(tree);
printRecords(finalTree);
}
public static void printRecords(
TreeMap<String, LinkedHashSet<Node>> recordTree) {
System.out.println("---------Records---------");
for (Map.Entry<String, LinkedHashSet<Node>> entry : recordTree
.entrySet()) {
System.out.println(entry.getKey());
// Print out the structured data
StringBuilder stringBuilder = new StringBuilder();
Iterator<Node> iterator = entry.getValue().iterator();
while (iterator.hasNext()) {
Node node = iterator.next();
for (int i = 0; i < node.index; i++) {
stringBuilder.append("-");
}
System.out.println(stringBuilder.toString() + node.value);
// "reset" the builder
stringBuilder.setLength(0);
}
}
}
private static TreeMap<String, LinkedHashSet<Node>> convertListToSet(
TreeMap<String, List<String>> tree) {
TreeMap<String, LinkedHashSet<Node>> finalMap = new TreeMap<String, LinkedHashSet<Node>>();
LinkedHashSet<Node> linkedHashSet = new LinkedHashSet<Node>();
// Iterate the entry set
for (Map.Entry<String, List<String>> entry : tree.entrySet()) {
List<String> records = entry.getValue();
for (String record : records) {
String[] recordArray = record.split("\\.");
for (int i = 1; i < recordArray.length; i++) {
Node node = new Node(i, Integer.parseInt(recordArray[i]));
linkedHashSet.add(node);
}
}
finalMap.put(entry.getKey(), linkedHashSet);
// reset our linkedHashSet
linkedHashSet = new LinkedHashSet<Node>();
}
System.out.println("Final map " + finalMap);
return finalMap;
}
/**
* Builds a tree with base record keys and a list of records for each key.
*
* @param data
* @return
*/
private static TreeMap<String, List<String>> buildBaseTree(List<String> data) {
TreeMap<String, List<String>> tree = new TreeMap<String, List<String>>();
List<String> recordList = null;
// First find all base records
for (String record : data) {
String[] baseEntry = record.split("\\.");
if (!tree.containsKey(baseEntry[0])) {
recordList = new ArrayList<String>();
tree.put(baseEntry[0], recordList);
}
}
// Now place all sub-records in each base record
for (String record : data) {
String[] baseEntry = record.split("\\.");
tree.get(baseEntry[0]).add(record);
}
System.out.println("------------------Base Tree---------------");
System.out.println(tree);
System.out.println("------------------------------------------");
return tree;
}
private static List<String> readData(String file) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(new File(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<String> data = new ArrayList<String>();
// Get a list of all the records
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
data.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Sort the list so its ordered
System.out.println("-------------Sorted Data Set-----------");
Collections.sort(data);
for (String record : data) {
System.out.println(record);
}
System.out.println("---------------------------------------");
return data;
}
}
Node.java
public class Node implements Comparable<Node> {
int index;
int value;
public Node(int index, int value) {
this.index = index;
this.value = value;
}
public int getIndex() {
return index;
}
@Override
public String toString() {
return "Node [index=" + index + ", value=" + value + "]";
}
public void setIndex(int index) {
this.index = index;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public int compareTo(Node o) {
Node otherNode = (Node) o;
if (this.index > otherNode.index)
return 1;
if (this.index < otherNode.index) {
return -1;
}
return 0;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + index;
result = prime * result + value;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (index != other.index)
return false;
if (value != other.value)
return false;
return true;
}
}
答案 0 :(得分:1)
它不必复杂。您所需要的只是SortedMap
SortedMap
个实例,并且只有一个技巧:为了类型安全而递归地对其进行参数化(如果需要)。
package com.acme;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
List<String> rows = new ArrayList<>();
rows.add("1.2.3.4.5");
rows.add("1.3.2.4.5");
rows.add("1.2.4.5.6");
MyTreeMap root = new MyTreeMap();
for (String row : rows) {
MyTreeMap n = root;
String[] cells = row.split("\\.");
for (String cell : cells) {
MyTreeMap child = n.get(cell);
if (child == null) {
n.put(cell, child = new MyTreeMap());
}
n = child;
}
}
print(root, "", "-");
}
static void print(MyTreeMap m, String indentationStr, String indentationStrAddition) {
for (Entry<String, MyTreeMap> o : m.entrySet()) {
System.out.println(indentationStr + o.getKey());
print(o.getValue(), indentationStr + indentationStrAddition, indentationStrAddition);
}
}
/**
* This is just a construct that helps us to parameterize recursively.
*/
static class MyTreeMap extends TreeMap<String, MyTreeMap> {private static final long serialVersionUID = 1L;}
}
答案 1 :(得分:0)
如果我了解您的问题,您想要从共享公共前缀的整数列表中创建搜索树。如果是这样,那么我认为你可以用更少的代码来实现这个目标:
private static class TreeNode {
private final Map<Integer, TreeNode> children = new HashMap<>();
public void insert(List<Integer> values) {
if (!values.isEmpty()) {
children.putIfAbsent(values.get(0), new TreeNode());
children.get(values.get(0)).insert(values.subList(1, values.size()));
}
}
public void print(int level) {
for (Map.Entry<Integer, TreeNode> entry : children.entrySet()) {
System.out.print(String.join("", Collections.nCopies(level, "-")));
System.out.println(entry.getKey());
entry.getValue().print(level + 1);
}
}
}
我不确定您是否打算对整数列表进行排序。如果是这样,您可以在代码中的适当位置添加Collections.sort
。