Arrays 如何识别和删除文件夹列表中的子文件夹?

Arrays 如何识别和删除文件夹列表中的子文件夹?,arrays,algorithm,Arrays,Algorithm,假设我有一个数组中的文件夹列表: 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中。最好的方法是什么 我不知道这是否是解决您的问题的最佳方法,但在找到它的过

假设我有一个数组中的文件夹列表:

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
中。最好的方法是什么

我不知道这是否是解决您的问题的最佳方法,但在找到它的过程中还是有一些启发的

首先,代码

/**
 * 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();
            }
        }
    }
}

解释

这里的想法是模拟一棵树

因此,首先我们添加所有父文件夹;这是通过按路径长度对数组进行排序来完成的

然后,每次我们添加成功的路径时,它都将被标记为leaf。当我们尝试添加另一条路径时,它“更大”,代码将知道它是一个子路径,因此我们将其删除


编辑:


对不起。。。我没有看到这个问题被标记为Java问题。

您可以先按升序对数组排序,然后按升序访问每个文件夹。然后跟踪以无效名称开头的“父”文件夹:

 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文件夹=[
“c:\\aaa\\bbb”,
'd:\\aaa\\bbb',
“c:\\aaa\\bbb\\ccc”,
'c:\\aaa\\bbb\\ccc\\ddd'
];
folders.sort();
让parent='>';
让结果=[];
对于(var i=0;iconsole.log(result.join('\n'))path = d:\aaa\bbb
path = c:\aaa\bbb
 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