我有一个任务,我一直在缠绕我的大脑,仍然有一个麻烦补充它。这就是:有一个班级:
public class Package {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private List<Package> dependencies;
public List<Package> getDependencies() {
return dependencies;
}
public void setDependencies(List<Package> dependencies) {
this.dependencies = dependencies;
}
public Package(String name){
this.name = name;
this.dependencies = new ArrayList<Package>();
}
//any bunch of methods here))
}
另外还有一个:
public class Project {
private String name;
private List<Package> packages = new ArrayList<Package>();
public boolean hasCyclic(){
//**//implementation should be here
}
}
我需要查找项目中的包列表是否具有循环依赖性。例如,A-> B-> C-> B-发现,返回真或A-> C-> Z-> A-找到,返回真。 首先想到的是获取所有包的名称,对它们进行排序并查找重复项。但是在某个地方,在我的大脑深处,有些东西告诉我它不是最理想的解决方案。你能帮助我吗?非常感谢你。
答案 0 :(得分:3)
这基本上是“有向图中的检测周期”问题。
我无法击败已在SO中发布的answer解释如何解决此问题。
答案 1 :(得分:2)
有一个周期&lt; ==&gt; DFS林(从任何起点)都有一个后分支。
线性运行时间。简单的实施。
答案 2 :(得分:1)
将项目的依赖关系视为树,然后只需对树进行深度优先遍历,在访问每个节点时跟踪包名称。如果在遍历到达最高级别之前遇到重复的名称,那么您就具有循环依赖性。
答案 3 :(得分:0)
有许多变体具有不同的内存/执行时间特征。一些想法是
答案 4 :(得分:0)
这就是我提出的代码。似乎工作)
package com.mycompany.app;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class Package {
private String name;
private List<Package> dependencies;
private List<String> allNames = new ArrayList<String>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Package> getDependencies() {
return dependencies;
}
public void setDependencies(List<Package> dependencies) {
this.dependencies = dependencies;
}
public Package(String name){
this.name = name;
this.dependencies = new ArrayList<Package>();
}
public boolean hasPackages(){
return !dependencies.isEmpty();
}
public List<String> getAllNames(){
allNames = new ArrayList<String>();
allNames.add(name);
for (Package pkg : dependencies){
if (pkg.hasPackages()){
allNames.addAll(pkg.getAllNames());
}
else{
allNames.add(pkg.getName());
}
}
return allNames;
}
public Package addPackage(Package pkg){
dependencies.add(pkg);
return this;
}
public boolean hasCyclic(){
List<String> names = getAllNames();
Set<String> visited = new HashSet<String>();
for (String name : names){
if (visited.contains(name)){
return true;
}
else{
visited.add(name);
}
}
return false;
}
}