我们说我有一个数组中的文件夹列表:
c:\aaa\bbb
d:\aaa\bbb
c:\aaa\bbb\ccc
c:\aaa\bbb\ccc\ddd
我的程序将以递归方式对这些文件夹中的每个对象执行一些操作。但正如您所看到的,此数组中的某些文件夹具有父子关系。所以我应该在进程之前删除此数组中的嵌套文件夹。对于上面的示例,c:\aaa\bbb\ccc\ddd
和c:\aaa\bbb\ccc
将被移除,因为它们嵌套在c:\aaa\bbb
中。最好的方法是什么?
答案 0 :(得分:0)
我不知道这是否是解决问题的最佳方法,但在此过程中找到它是一些明智之处。
首先,代码。
/**
* Created by Zack at 14/January/2017
*/
public class ChildPathRemover {
private final Node mRoot = new Node();
/**
*
* @param path
* @return True if the directory was added, False if is a child directory
*/
public boolean add(String path) {
Node currNode = mRoot;
String[] parts = path.split(Pattern.quote(File.separator));
for (int i = 0; i < parts.length; i++) {
// contains
Node nextNode = currNode.subNodes.get(parts[i]);
if (nextNode != null) {
// Already has a parent
if (nextNode.isLeaf) {
return false;
} // Process the nextNode
else {
currNode = nextNode;
}
} // Reached the end, so we a good to add new path
else {
for (int k = i; k < parts.length; k++) {
Node newNode = new Node();
currNode.subNodes.put(parts[k], newNode);
currNode = newNode;
}
currNode.isLeaf = true;
break;
}
}
// TODO: if the parent were not added first, you will need to rebuild the paths, based on the
// Nodes and then call the Remove Listener
return true;
}
private static class Node {
boolean isLeaf = false;
HashMap<String, Node> subNodes = new HashMap<>();
}
public interface RemoveListener {
void pathRemoved(String path);
}
/**
* Call this method to remove the child paths
*
* @param paths
*/
public static void removeChildPath(List<String> paths) {
// Sort by the length of the path
Collections.sort(paths, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
});
ChildPathRemover cpr = new ChildPathRemover();
Iterator<String> itr = paths.iterator();
while (itr.hasNext()) {
if (!cpr.add(itr.next())) {
itr.remove();
}
}
}
}
如何使用的示例。
public static void main(String[] args) {
ArrayList<String> paths = new ArrayList<>();
paths.add("d:\\aaa\\bbb");
paths.add("c:\\aaa\\bbb\\ccc");
paths.add("c:\\aaa\\bbb\\ccc\\ddd");
paths.add("c:\\aaa\\bbb");
removeChildPath(paths);
for (String path : paths) {
System.out.println("path = " + path);
}
}
此示例将生成
path = d:\aaa\bbb
path = c:\aaa\bbb
<强>解释强>
这里的想法是模拟一棵树。
首先我们添加所有父文件夹;这是通过按路径长度对数组进行排序来完成的。
然后,每次我们添加成功的路径时,它都会被标记为叶子。当我们尝试添加另一个路径并且它“更大”时,代码将知道它是一个孩子,所以我们删除它。
编辑:
抱歉......我没有看到这个问题是不标记为Java问题......
答案 1 :(得分:0)
您可以先按升序对数组进行排序,然后按顺序访问每个文件夹。然后跟踪父母&#34;文件夹,以无效名称开头:
sort folders
parent = '>'
result = []
for each folder in folders:
if folder does not start with parent followed by a slash:
# keep folder, and remember it as potential parent
append folder to result
parent = folder
这是一个JavaScript代码示例:
var folders = [
'c:\\aaa\\bbb',
'd:\\aaa\\bbb',
'c:\\aaa\\bbb\\ccc',
'c:\\aaa\\bbb\\ccc\\ddd'
];
folders.sort();
let parent = '>';
let result = [];
for (var i = 0; i < folders.length; i++) {
if (folders[i].indexOf(parent + '\\') != 0) {
result.push(folders[i]); // keep it
parent = folders[i]; // and remember this as potential parent
}
}
// Display result
console.log(result.join('\n'));
&#13;