ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【树型问题】从一次不太合理的需求中引发一个思考题

2021-08-01 12:57:36  阅读:194  来源: 互联网

标签:1.1 1.2 思考题 update departments 不太 2.2 树型 节点


需求:在部门管理中,如果某个管理员对父部门拥有权限,则对其部门及其以下任何部门都有权限;如果对某个部门对所有子部门拥有权限,则表示对其父部门拥有权限。

问题:现有一组含父部门节点和子部门节点的集合,根据已知的部门树形结构,要求消除含有父子关系节点,只保留最大权限的节点,例如:部门树形结构为[1, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 2, 2.1, 2.2, 3, 4],部门1.1表示是1的子部门,1.2.1表示1.2的子部门,依此类推。
用例

部门树结构:[1, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 2, 2.1, 2.2, 3, 4]
    egg1:(增加节点,减少子节点,用子节点替代父节点)
        管理者A权限:department_a=[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3]
        管理者B权限:department_b=[1.2.3, 2, 4]
        B操作步骤:给A增加权限[2,4],并去掉[1.2.3]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2, 4]
        A的最后结果应为:[1.1, 1.2.1, 1.2.2, 2, 4]
    egg2:(增加子节点补全,用父节点替代子节点)
        管理者A权限:department_a=[1.1, 1.2, 1.2.1, 1.2.2, 2, 4]
        管理者B权限:department_b=[1.2.3, 2, 4]
        B操作步骤:给A去掉权限[2,4],并增加 [1.2.3]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3]
        A的最后结果应为:[1]
    egg3:(减少子节点,增加子节点,用父节点替代子节点)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A去掉权限[2.2],并增加 [1.2.3]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 1.2.3, 4]
        A的最后结果应为:[1, 2.1, 4]
    egg4:(减少父节点,增加子节点,用父节点替代子节点)(?)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A去掉权限[2],并增加 [1.2.3]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 4]
        A的最后结果应为:[1, 4]
    egg5:(减少子节点)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A去掉权限[2.2]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 4]
        A的最后结果应为:[1.1, 1.2.1, 1.2.2, 4]
    egg6:(减少父节点)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A减少权限[2]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 4]
        A的最后结果应为:[1.1, 1.2.1, 1.2.2, 4]
    egg7:(增加子节点)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A增加权限[2.2]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2.2, 4]
        A的最后结果应为:[1, 4]
    egg8:(增加父节点)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A增加权限[2]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 4]
        A的最后结果应为:[1, 2, 4]
    egg9:(增加子节点,(无父节点),用父节点替代子节点)
        管理者A权限:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 2.2, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A增加权限[2.1]
        传参数:update_departments=[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 2.1, 2.2, 4]
        A的最后结果应为:[1, 2, 4]
    egg10:(删除子节点)
        管理者A权限:update_departments=[1, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 2, 2.1, 2.2, 3, 4]
        管理者B权限:[1.2.3, 2, 2.1, 2.2, 4]
        B操作步骤:给A删除权限[1.2.3]
        传参数:update_departments=[0, 1, 1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 3, 4]
        A的最后结果应为:[1.1, 1.2.1, 1.2.2, 2, 3, 4]
# coding:utf-8


def is_all_children(children, departments):
    """
    该节点是否含有全部子节点
    :param children:
    :param departments:
    :return:
    """

    res = []
    for n in departments:
        if n in children:
            res.append(n)

    if len(res) == 0:
        # 无子情况
        return -1

    return 0 if set(res) == set(children) else 1


def exists_parent(departments, p_c_dpts):
    """
    判断父子关系
    :param departments:
    :param p_c_dpts:
    :return:
    """

    for k, v in p_c_dpts.items():
        if k in departments and v in departments:
            return True

    return False


def get_merge_departments(departments):
    """
    将更新前后部门数据合并,组成新的部门集合
        特别注意:
        错误做法:1)包括全部子节点即删除子节点,这是错误的,必须从叶子节点开始检查。
         1
         1.1
          1.1.1
            1.1.1.1
            1.1.1.2
            1.1.1.3 (x)
          1.1.2
          1.1.3
         1.2
        说明:如果发现1.1的子节点都在,删除了即保留1.1,这是明显错误的,他只有(1.1.1.1, 1.1.1.2, 1.1.2, 1.1.3)
        2)不包括全部子节点即删除父节点,这是正确的。
        正确解法:先找到可删除的父节点进行删除,然后对包括全部子节点进行如下处理:(1)删除子节点,保留或增加父节点;
        (2)循环遍历,因为新增的父节点可能构成全部子节点中的一个节点,直到不同时存在父子关系的节点为止。

        是否存在父子关系?
            存在:1)处理不包括全部子节点的父节点立即删除(循环处理完)
                 2)包括全部子节点进行处理:删除子节点,保留或增加父节点(循环处理完)
            不存在:看兄弟节点能否组成一个某个父节点的全部子节点,回2)返回结果
    """

    # 保存父子关系,判断是否包含全部子节点
    p_dpts = {
             '1': ['1.1', '1.2'],
             '1.2': ['1.2.1', '1.2.2', '1.2.3'],
             '2': ['2.1', '2.2']
    }
    p_c_dpts = {
        '1.1': '1',
        '1.2': '1',
        '1.2.1': '1.2',
        '1.2.2': '1.2',
        '1.2.3': '1.2',
        '2.1': '2',
        '2.2': '2'
    }

    while True:
        if not exists_parent(departments, p_c_dpts):
            return departments

        # 处理不包括全部子节点的父节点立即删除(父子同时存在)
        flag = list()
        for index, up in enumerate(departments):
            if p_dpts.get(up) and is_all_children(p_dpts[up], departments) == 1:
                flag.append(up)

        # 进行删除
        for item in flag:
            departments.remove(item)

        flag = list()
        for index, up in enumerate(departments):
            if p_dpts.get(up) and is_all_children(p_dpts[up], departments) == 0:
                flag += p_dpts[up]

        # 进行删除
        for item in flag:
            departments.remove(item)

        # 兄弟节点能否合并
        flag = dict()
        for k, v in p_dpts.items():
            if not set(v).difference(set(departments)):
                flag[k] = v

        # 删除子节点,增加父节点
        for k, v in flag.items():
            departments.append(k)
            for i in v:
                departments.remove(i)


if __name__ == '__main__':

    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 2, 4]
    # A的最后结果应为:[1.1, 1.2.1, 1.2.2, 2, 4]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '2', '4']
    print("[1.1, 1.2.1, 1.2.2, 2, 4] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 1.2.3]
    # A的最后结果应为:[1]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '1.2.3']
    print("[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 1.2.3]
    # A的最后结果应为:[1, 2.1]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '1.2.3', '2', '2.1']
    print("[1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 1.2.3] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 4]
    # A的最后结果应为:[1, 4]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '1.2.3', '4']
    print("[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 4] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 4]
    # A的最后结果应为:[1.1, 1.2.1, 1.2.2, 4]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '4']
    print("[1.1, 1.2, 1.2.1, 1.2.2, 4] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 4]
    # A的最后结果应为:[1, 2, 4]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '2', '2.1', '2.2', '4']
    print("[1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 4] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 2.1, 2.2, 4]
    # A的最后结果应为:[1, 2, 4]
    update_departments = ['1.1', '1.2', '1.2.1', '1.2.2', '1.2.3', '2.1', '2.2', '4']
    print("[1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 2.1, 2.2, 4] = ", get_merge_departments(update_departments))
    # 传参数:update_departments = [1, 1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 4]
    # A的最后结果应为:[1.1, 1.2.1, 1.2.2, 2, 4]
    update_departments = ['1', '1.1', '1.2', '1.2.1', '1.2.2', '2', '2.1', '2.2', '4']
    print("[1, 1.1, 1.2, 1.2.1, 1.2.2, 2, 2.1, 2.2, 3, 4] = ", get_merge_departments(update_departments))

标签:1.1,1.2,思考题,update,departments,不太,2.2,树型,节点
来源: https://blog.csdn.net/TIANTANGDEGEZI/article/details/119284530

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有