有一个班级Company
,它引用了Company
的另一个实例来代表parent
。可以说有四家公司c1
,c2
,c3
& c4
和c2
,c3
,c4
已将母公司设为c1
。
例如:
public class Company {
public Company parent;
public Company() { }
public Company(Company parent) {
this.parent = parent;
}
public static void main(String[] args) {
Company c1 = new Company();
Company c2 = new Company(c1);
Company c3 = new Company(c1);
Company c4 = new Company(c1);
}
如果我们将c2
设置为c1
的母公司:
c1.parent = c2;
然后它将在公司层次结构中创建一个Cyclomatic Complexity无限循环,我们必须在系统中避免这种循环。
我们希望能够在运行时检测到 。在上述情况下,检查同一类对象的圈复杂度的最佳算法是什么?
答案 0 :(得分:6)
您的任务与圈复杂度无关。您的实体基本上形成一个图形,并且您想要检测其中的循环。常见的方法是执行DFS。
您可以找到大量示例over the internet。
答案 1 :(得分:1)
我已经以编程方式解决了这个问题,创建了一个本地Set
个已处理对象,并让它在每次调用递归方法时作为输入参数传播。
例如:
public void myMethod(Company c)
{
Set<Company> visitedCompanies=new HashSet<Company>();
visitedCompanies.add(c);
myPrivateMethod(c, visitedCompanies);
}
private void myPrivateMethod(Company c, Set<Company> visitedCompanies)
{
if (visitedCompanies.contains(c))
{
// Cylce detected
}
else
{
//... do some stuff
// Go upwards in the hierarchy
if (c.getParent()!=null)
{
visitedCompanies.add(c);
myPrivateMethod(c.getParent(), visitedCompanies);
}
}
对于科西嘉,您必须先确保您的班级公司是可转化的:它会正确覆盖hashCode
和equals
。
请注意,此算法甚至可以在公司抽象之外实现(如本例所示),因为它在每个调用中传播Company对象作为遍历状态的一部分(以及集合)。这不是强制性的,因为这些方法本身可能是公司抽象的一部分,但 必须将该集合作为输入参数传播。
答案 2 :(得分:0)
您可以将private async void Button_Click(object sender, RoutedEventArgs e)
{
await LoadingDialogAsync();
SaveAndLoadData.SaveUserData(ApplicationData.UserData);
MainWindowLogic.LogIntoWebsites();
}
private async Task LoadingDialogAsync()
{
var controller = await this.ShowProgressAsync("Logging In...", "");
}
设置为parent
,并使用方法private
更改parent
的值。然后:
setParent(Company)
通常不好的做法是使用public boolean setParent(Company parent) {
Company curr = parent;
while (curr != null) {
if (curr.equals(this)) {
return false; // Failed as cycle
} else {
curr = curr.getParent();
}
}
this.parent = parent;
return true;
}
变量,因为它会破坏封装。
如果您无法将字段更改为public
,则:
private
修改:更改public List<Company> hasCycle(List<Company> companies) {
while (companies.size() > 0) {
List<Company> cycle = new ArrayList<Company>();
Company curr = companies.get(companies.length() - 1);
cycle.add(curr);
while (curr.parent != null) {
curr = curr.parent;
if (cycle.contains(curr)) {
return cycle; // Cycle detected
}
cycle.add(curr);
}
companies.removeAll(cycle); // Remove all elements we traversed through just now
}
return null;
}
的返回值,以返回包含所有公司的hasCycle
进行进一步处理(打印出来,删除等)。