如何知道是否有一轮是由父母引起的(A=>B=>C=>A)

发布于 2024-11-02 01:13:43 字数 652 浏览 2 评论 0原文

我有以下结构:

[Employee]
ID
Manager1ID
Manager2ID

场景:

我想进行验证以确保所选的 Manager1 或 Manager2 不会导致回合。换句话说,我想知道这种情况是否存在:

A 的经理是 B & B 的经理是 C,C 的经理也是 A // 无效

A =>; B => C=> A

告诉用户 A 不是 C 的有效经理,因为 C 已经是 A 的经理 。


问题:

我想在一个 while 循环中将管理器作为树中的父级进行检查,当我在列表中找到所选的管理器时,我知道它是无效的。 (对于 Manager1 和 Manager2 的两个列表有两个循环)

问题是每个员工可能有两个经理,并且在这样的情况下可能存在一轮:

A =>; B(经理1)=> C(经理2)=>

Which 无法签入我建议的解决方案。

任何想法!

I have the following structure:

[Employee]
ID
Manager1ID
Manager2ID

Scenario:

I want to make a validation to ensure that the chosen Manager1 or Manager2 does not cause a round. In other words, I want to know whether this case exists:

The manager of A is B & the manager of B is C and the manger of C is also A // not valid

A => B => C => A

To tell the user that A is not a valid manager for C because C is already a manager of A
.


The problem:

I though of checking in a while loop the managers as parents in a tree, and when I found the chosen manager in the list I know that it is not valid. (Two loops for tow lists for Manager1 and Manager2)

The problem is that every employee might have two managers and a round maybe exists in a case like this:

A => B (Manager1) => C (Manager2) => A

Which is not able to check in my suggested solution.

Any idea!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

∞觅青森が 2024-11-09 01:13:43

从有问题的员工开始,对经理组进行广度优先搜索,并不断累积您在列表中遇到的经理列表。每次向列表中添加条目时,请检查它是否会创建重复项。如果是这样,则意味着您已达到您想要检查的条件。继续此过程,直到遇到重复条件或到达没有管理器的节点

starting from the employee in question, do a breadth first search on the set of managers and keep accumulating the list of managers you come across in a list. Each time you add an entry to the list, check if it would create a duplication. If it would, it means you have reached the condition you wanted to check for. Keep continuing this process until you either hit a duplication condition or you reach a node which does not have managers

夏日浅笑〃 2024-11-09 01:13:43

使用递归函数:

List<Employee> lineage = new List<Employee>();
Validate(theUser, lineage);

public void Validate(Employee employee, List<Employee> lineage)
{
  if (lineage.Contains(employee))
     throw new InvalidOperationException("Circular graph");

  lineage.Add(employee);

  if (employee.Manager != null)
    Validate(employee.Manager, lineage)
}

Use a recursive function:

List<Employee> lineage = new List<Employee>();
Validate(theUser, lineage);

public void Validate(Employee employee, List<Employee> lineage)
{
  if (lineage.Contains(employee))
     throw new InvalidOperationException("Circular graph");

  lineage.Add(employee);

  if (employee.Manager != null)
    Validate(employee.Manager, lineage)
}
金兰素衣 2024-11-09 01:13:43

我为n个被举报者提供了一个完整的通用解决方案,这比被举报者更符合逻辑。如果您想将报告者重命名为经理,您可以这样做。
您可以修改遍历以满足您的需要。我已经通过循环和不循环测试了这一点。看起来效果很好。让我知道这是否适合您。

using System;
using System.Collections.Generic;


namespace GenericDictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee("Employee", null);
            Employee manager = new Employee("Manager", employee);
            Employee CEO = new Employee("CEO", manager);
            CEO.AddReportee(new Employee("Manager2", employee));

            // Uncomment this line to see exception in action
            // employee.AddReportee(CEO);
            try
            {
                CEO.DisplayReportees();
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine();
                Console.WriteLine("***** Exception: " + ex.Message + " *****");
            }

            Console.ReadLine();
        }

        public class Employee
        {
            public List<Employee> Reportees { get; private set; }
            public string Name { get; private set; }
            public Employee(string name, Employee reportee)
            {
                this.Reportees = new List<Employee>();
                this.Name = name;
                this.Reportees.Add(reportee);
            }
            public void AddReportee(Employee reportee)
            {
                Reportees.Add(reportee);
            }
            int indentationCount = 0;
            List<Employee> traversedNodes = new List<Employee>();
            void DisplayReportees(Employee employee)
            {
                traversedNodes.Add(employee);
                for (int i = 0; i < indentationCount; i++)
                    Console.Write(" ");
                Console.WriteLine(employee.Name);
                indentationCount = indentationCount + 3;

                foreach (Employee reportee in employee.Reportees)
                {
                    if (AlreadyTraversed(reportee))
                        throw new InvalidOperationException("Circular graph at node " + reportee.Name);
                    if (reportee != null)
                        DisplayReportees(reportee);
                }
                indentationCount = indentationCount - 3;
                traversedNodes.Remove(employee);
            }

            bool AlreadyTraversed(Employee employee)
            {
                return traversedNodes.Contains(employee);
            }

            public void DisplayReportees()
            {
                DisplayReportees(this);
            }
        }
    }
}

I have provided a complete generic solution for n number of reportees which is more logical than reportees. If you like to rename reportees to managers, you can do so.
You can modify the traversal to suit your needs. I have tested this with cycle and without cycle. It seems to work fine. Let me know if this works for you.

using System;
using System.Collections.Generic;


namespace GenericDictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee("Employee", null);
            Employee manager = new Employee("Manager", employee);
            Employee CEO = new Employee("CEO", manager);
            CEO.AddReportee(new Employee("Manager2", employee));

            // Uncomment this line to see exception in action
            // employee.AddReportee(CEO);
            try
            {
                CEO.DisplayReportees();
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine();
                Console.WriteLine("***** Exception: " + ex.Message + " *****");
            }

            Console.ReadLine();
        }

        public class Employee
        {
            public List<Employee> Reportees { get; private set; }
            public string Name { get; private set; }
            public Employee(string name, Employee reportee)
            {
                this.Reportees = new List<Employee>();
                this.Name = name;
                this.Reportees.Add(reportee);
            }
            public void AddReportee(Employee reportee)
            {
                Reportees.Add(reportee);
            }
            int indentationCount = 0;
            List<Employee> traversedNodes = new List<Employee>();
            void DisplayReportees(Employee employee)
            {
                traversedNodes.Add(employee);
                for (int i = 0; i < indentationCount; i++)
                    Console.Write(" ");
                Console.WriteLine(employee.Name);
                indentationCount = indentationCount + 3;

                foreach (Employee reportee in employee.Reportees)
                {
                    if (AlreadyTraversed(reportee))
                        throw new InvalidOperationException("Circular graph at node " + reportee.Name);
                    if (reportee != null)
                        DisplayReportees(reportee);
                }
                indentationCount = indentationCount - 3;
                traversedNodes.Remove(employee);
            }

            bool AlreadyTraversed(Employee employee)
            {
                return traversedNodes.Contains(employee);
            }

            public void DisplayReportees()
            {
                DisplayReportees(this);
            }
        }
    }
}
凉栀 2024-11-09 01:13:43

使用以下递归函数:

Boolean CheckManagers(Employee emp)
{

    if ((emp.Manager1ID.HasValue && emp.Manager1ID == emp.ID) ||
       (emp.Manager2ID.HasValue && emp.Manager2ID == emp.ID)) return false;

    return 
    (
        (!emp.Manager1ID.HasValue || (emp.Manager1ID.HasValue && CheckManagers((Employee) emp.Manager1)) && 
        (!emp.Manager2ID.HasValue || (emp.Manager2ID.HasValue && CheckManagers((Employee) emp.Manager2))
    );

}

Use the following recursive function:

Boolean CheckManagers(Employee emp)
{

    if ((emp.Manager1ID.HasValue && emp.Manager1ID == emp.ID) ||
       (emp.Manager2ID.HasValue && emp.Manager2ID == emp.ID)) return false;

    return 
    (
        (!emp.Manager1ID.HasValue || (emp.Manager1ID.HasValue && CheckManagers((Employee) emp.Manager1)) && 
        (!emp.Manager2ID.HasValue || (emp.Manager2ID.HasValue && CheckManagers((Employee) emp.Manager2))
    );

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文