C# 查找文件夹循环引用

C# 查找文件夹循环引用,c#,.net,algorithm,logic,C#,.net,Algorithm,Logic,假设我有一个应用程序,可以将主文件夹中的文件传输到其他位置 例如,用户可以按如下方式配置应用程序: If placed in C:\X\A Transfer to C:\Z\A If placed in C:\Y\B Transfer to C:\Z\B . . . . . . 到现在为止,一切都很好。但以下配置将创建无止境的传输循环: if placed in C:\X\A Transfer to C:\Z\A if placed in C:\Z\A Transfer to C:\Z\B i

假设我有一个应用程序,可以将主文件夹中的文件传输到其他位置

例如,用户可以按如下方式配置应用程序:

If placed in C:\X\A Transfer to C:\Z\A
If placed in C:\Y\B Transfer to C:\Z\B
. . .
. . .
到现在为止,一切都很好。但以下配置将创建无止境的传输循环:

if placed in C:\X\A Transfer to C:\Z\A
if placed in C:\Z\A Transfer to C:\Z\B
if placed in C:\Z\B Transfer to C:\X\A

这样的层次结构可能会变得相当复杂。首先,预测它们并防止这种配置的最佳方法是什么?

您基本上是在有向图中寻找循环。我会使用像QuickGraph这样的图形库:

您基本上是在有向图中查找循环。我会使用像QuickGraph这样的图形库:

假设有这样一个类:

class Rule
{
    public string sourceDir; // dir file placed
    public string targetDir; // dir to move to
}
public bool RuleCausesCycle(Rule rule)
{
    return RuleCausesCycle(rule, new HashSet(CaseInsensitiveComparer.Default));
}

private bool RuleCausesCycle(Rule rule, Set visited)
{
     Rule targetRule;

     if (visited.Contains(rule.sourceDir))
     {
         return true;
     }

     if (rules.TryGetValue(rule.targetDir, out targetRule))
     {
         visited.Add(rule.sourceDir);

         return RuleCausesCycle(targetRule, visited);
     }

     return false;
}
以及一个包含由
sourceDir
索引的所有规则的字典,命名为
rules

您可以编写如下函数:

class Rule
{
    public string sourceDir; // dir file placed
    public string targetDir; // dir to move to
}
public bool RuleCausesCycle(Rule rule)
{
    return RuleCausesCycle(rule, new HashSet(CaseInsensitiveComparer.Default));
}

private bool RuleCausesCycle(Rule rule, Set visited)
{
     Rule targetRule;

     if (visited.Contains(rule.sourceDir))
     {
         return true;
     }

     if (rules.TryGetValue(rule.targetDir, out targetRule))
     {
         visited.Add(rule.sourceDir);

         return RuleCausesCycle(targetRule, visited);
     }

     return false;
}

假设有这样一个类:

class Rule
{
    public string sourceDir; // dir file placed
    public string targetDir; // dir to move to
}
public bool RuleCausesCycle(Rule rule)
{
    return RuleCausesCycle(rule, new HashSet(CaseInsensitiveComparer.Default));
}

private bool RuleCausesCycle(Rule rule, Set visited)
{
     Rule targetRule;

     if (visited.Contains(rule.sourceDir))
     {
         return true;
     }

     if (rules.TryGetValue(rule.targetDir, out targetRule))
     {
         visited.Add(rule.sourceDir);

         return RuleCausesCycle(targetRule, visited);
     }

     return false;
}
以及一个包含由
sourceDir
索引的所有规则的字典,命名为
rules

您可以编写如下函数:

class Rule
{
    public string sourceDir; // dir file placed
    public string targetDir; // dir to move to
}
public bool RuleCausesCycle(Rule rule)
{
    return RuleCausesCycle(rule, new HashSet(CaseInsensitiveComparer.Default));
}

private bool RuleCausesCycle(Rule rule, Set visited)
{
     Rule targetRule;

     if (visited.Contains(rule.sourceDir))
     {
         return true;
     }

     if (rules.TryGetValue(rule.targetDir, out targetRule))
     {
         visited.Add(rule.sourceDir);

         return RuleCausesCycle(targetRule, visited);
     }

     return false;
}

同意。另见本SO主题:同意。另请参阅本SO主题:简单而明显的解决方案是,每个文件只遵循自上而下的规则。简单而明显的解决方案是,每个文件只遵循自上而下的规则。如果假设每个源目录只有一个目标目录(您不从同一源目录复制两个副本),则,这是一个比其他答案更好的解决方案。如果它不起作用,您可以添加一个循环(并且不使用字典),但它可能会非常快地消耗大量资源。如果您有多个相同源的规则,则需要一个带有列表的字典。除非您有数百万条规则,否则它不会变得资源密集或缓慢。如果假设每个源目录只有一个目标目录(您不会从同一个源目录复制两个副本),那么这是一个比另一个更好的解决方案。如果它不起作用,您可以添加一个循环(并且不使用字典),但它可能会非常快地消耗大量资源。如果您有多个相同源的规则,则需要一个带有列表的字典。除非你有数百万条规则,否则它不会变得资源密集或缓慢