自定义一个跟节点。每个节点都一个前缀(subString),代表他们的路径,如果相同,则是同一个目录。
是用Java的TreeSet可以自动排序。
解释在代码注释里了。
网上也有用字典树的。还有一种简单的方法是a/b/c, 可以看成是文件 a,a/b,a/b/c 这样把所有的文件按照自定义规则排序,在输出就行了。
public class PathPrint_1090 {
static int n;
static Node root; //定义一个根节点
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
n = scanner.nextInt();
if(n == 0)
break;
String str;
Node root = new Node();
root.key = "";
root.subString = "";
root.children = new TreeSet<Node>();
for (int i = 0; i < n; i++) {
str = scanner.next();
root.addChild(new Node(str.split("\\\\"), 0, root)); //将读入的一个字符串分割为一个字符数组,构造一个链表
}
root.print();
System.out.println();
}
}
}
class Node implements Comparable<Node> {
public String key; //需要输出的名称
public String subString; //前缀,相同则为一个目录
public TreeSet<Node> children; //子节点。个数不定
public Node father; //父节点
public int pre; //代表偏移量
public int compareTo(Node o) { //定义比较函数。即比较前缀 a\b\ == a\b\, 是一个目录
return this.subString.compareTo(o.subString);
}
public Node() {}
//根据一个字符数组,构造一个节点串.
public Node(String str[], int index, Node f) {
this.subString = "";
if (index == str.length) //到了最后就直接返回
return;
for (int i = 1; i <= index; i++)
this.subString += str[i] + '\\'; //获得前缀
if (index == 0)
this.subString = str[0];
this.key = str[index];
this.pre = f.pre + f.key.length() + 1; //偏移量等于父节点的偏移量 + 父节点长度
this.father = f;
if (index != str.length) {
if (this.children == null)
this.children = new TreeSet<Node>();
children.add(new Node(str, index + 1, this));
}
}
public void addChild(Node n) { //添加一个孩子节点
//由于孩子节点可能重复,重新合并
if (children.contains(n)) {
Node temp = null;
for (Node temp2 : children) {
if (temp2.compareTo(n) == 0)
temp = temp2;
}
temp.addChild(n.children.first());
} else {
children.add(n);
}
}
public void print() {
if (this.key == null)
return;
if(this.key != ""){
pre--; //由于第一个位置会多个空格
while (pre-- > 0)
System.out.print(" ");
System.out.println(key);
}
if (this.children != null && children.size() > 0) {
for (Node n : children)
n.print();
}
}
}