【树型问题】从一次不太合理的需求中引发一个思考题
作者:互联网
需求:在部门管理中,如果某个管理员对父部门拥有权限,则对其部门及其以下任何部门都有权限;如果对某个部门对所有子部门拥有权限,则表示对其父部门拥有权限。
问题:现有一组含父部门节点和子部门节点的集合,根据已知的部门树形结构,要求消除含有父子关系节点,只保留最大权限的节点,例如:部门树形结构为[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