如果我有两个路径,如何找到两个路径中最长的公共路径?
SELECT PKG_MATH.ARC(PKG_MATH.VECTOR(1,1,0),PKG_MATH.VECTOR(1,-1,0)) FROM DUAL;
预期输出:
import java.nio.file.Path;
import java.nio.file.Paths;
Path common(Path pathA, Path pathB) {
...
}
...
common(Paths.get("/a/b/c/d/e"), Paths.get("/a/b/c/g/h"))
答案 0 :(得分:2)
Path path1 = Paths.get("/a/b/c/d/e");
Path path2 = Paths.get("/a/b/c/g/h");
您可以相对于彼此的路径:
Path relativePath = path1.relativize(path2).normalize();
// result: ../../g/h
然后转到父级,直到路径以..
结束
while(relativePath != null && !relativePath.endsWith("..")) {
relativePath = relativePath.getParent();
}
// result: ../.. (but may also be null)
结果可以应用于两个路径中的任何一个:
Path result = path1.resolve(relativePath).normalize()
// result: /a/b/c
答案 1 :(得分:2)
尝试这个简单的想法
Path a = Paths.get("a/b/c/d/e");
Path b = Paths.get("a/b/c/g/h");
// Normalize
a = a.normalize();
b = b.normalize();
// Create common root
Path common = null;
if (a.isAbsolute() && b.isAbsolute() && a.getRoot().equals(b.getRoot())) {
common = a.getRoot();
}
else if (!a.isAbsolute() && !b.isAbsolute()) {
common = Paths.get("");
}
// Iterate from root until names differ
if (common != null) {
int n = Math.min(a.getNameCount(), b.getNameCount());
for (int i=0; i<n; i++) {
if (a.getName(i).equals(b.getName(i))) {
common = common.resolve(a.getName(i));
}
else {
break;
}
}
}
// Show
System.out.println(common);
答案 2 :(得分:1)
我们可以从可能的最长路径开始生成所有子路径,并检查哪两个相等:
private Path commonPath(Path path0, Path path1) {
if (path0.equals(path1)) {
return path0;
}
path0 = path0.normalize();
path1 = path1.normalize();
int minCount = Math.min(path0.getNameCount(), path1.getNameCount());
for (int i = minCount; i > 0; i--) {
Path sp0 = path0.subpath(0, i);
if (sp0.equals(path1.subpath(0, i))) {
String root = Objects.toString(path0.getRoot(), "");
return Paths.get(root, sp0.toString());
}
}
return path0.getRoot();
}
和用法:
Map<String, String> paths = new LinkedHashMap<>();
paths.put("/a/b/c", "/a/b/d");
paths.put("/a/", "/a/b/d");
paths.put("/f/b/c", "/a/b/d");
paths.put("/a/b/c/d/e", "/a/b/f/../c/g");
paths.put("C:/Winnt/System32", "C:/Winnt/System64");
paths.forEach((k, v) ->
System.out.println(
k + " = " + v + " => " + commonPath(Paths.get(k), Paths.get(v))));
上面的代码显示:
/a/b/c = /a/b/d => /a/b
/a/ = /a/b/d => /a
/f/b/c = /a/b/d => /
/a/b/c/d/e = /a/b/f/../c/g => /a/b/c
C:/Winnt/System32 = C:/Winnt/System64 => C:/Winnt