通常我们会要求您提供迄今为止编写的源代码,但如果我理解正确的话,它更多的是递归概念,而不是您要查找的代码本身,所以这里有解释递归概念的源代码。
还有其他方法可以做到这一点,但这个方法非常简单。正如我所看到的,您需要递归两次,因为叶子可能会相互影响(首先收集数据底部->顶部,然后传递数据顶部->底部)。
我在 c:/temp/zipper 下建立了一个文件夹结构来测试代码。以“m”开头的文件符合条件。希望 cmets 和 System.outs 解释发生了什么。
public class Zipper {
private static String NO_ZIP_MESSAGE = "";
// private static String NO_ZIP_MESSAGE = " (no zip)";
public static void main(String[] args) {
new Zipper().go("C:/temp/zipper");
}
private void go(String startingFolderStr) {
MyFile startingFolder = new MyFile(new File(startingFolderStr), false);
boolean zipStartingFolder = recurse(startingFolder, "");
System.out.println("------------------ " + zipStartingFolder);
cleanup(startingFolder, "", false);
}
private boolean recurse(MyFile folder, String indent) {
// Go through the folder structure top-down and check if individual files meet the criteria, and also update zip
// flag for folders in "direct descendance".
System.out.println(indent + folder.file.getName());
boolean allSiblingsMeetCriteria = true;
for (File f : folder.file.listFiles()) {
MyFile mf = new MyFile(f, false);
folder.siblings.add(mf);
if (f.isFile()) {
boolean meetsCriteria = f.getName().startsWith("m");
mf.zip = !meetsCriteria;
allSiblingsMeetCriteria = allSiblingsMeetCriteria && meetsCriteria;
System.out.println(indent + " " + f.getName() + (meetsCriteria ? "" : " --> ZIP"));
} else if (f.isDirectory()) {
allSiblingsMeetCriteria = recurse(mf, indent + " ") && allSiblingsMeetCriteria;
}
}
folder.zip = allSiblingsMeetCriteria;
System.out.println(
indent + "... " + folder.file.getName() + (allSiblingsMeetCriteria ? " --> ZIP" : NO_ZIP_MESSAGE));
return allSiblingsMeetCriteria;
}
private void cleanup(MyFile folder, String indent, boolean parentIsZipped) {
// If we come to a folder with zip=true, all its subfolders have zip=true and all its subfiles have zip=false.
// Set parentIsZipped=true, and go thru and set all subfolders to zip=false (1). Ignore subfiles since they are
// already ok.
// If we come to a folder with zip=false (and we're not in a 'true flow' (comment above)), all subfiles should
// have zip=true (2), but we leave subfolders as is
System.out.println(indent + folder.file.getName() + (folder.zip ? " --> ZIP" : NO_ZIP_MESSAGE));
parentIsZipped = parentIsZipped || folder.zip;
for (MyFile mf : folder.siblings) {
if (mf.file.isFile()) {
if (!parentIsZipped) {
mf.zip = true; // (2)
}
System.out.println(indent + " " + mf.file.getName() + (mf.zip ? " --> ZIP" : NO_ZIP_MESSAGE));
} else if (mf.file.isDirectory()) {
if (parentIsZipped) {
mf.zip = false; // (1)
}
cleanup(mf, indent + " ", parentIsZipped);
}
}
}
private class MyFile {
File file;
boolean zip;
List<MyFile> siblings;
public MyFile(File file, boolean zip) {
this.file = file;
this.zip = zip;
siblings = new ArrayList<>();
}
}
}