Python实现有趣的亲戚关系计算器

  • Post category:Python

实现亲戚关系计算器的完整攻略如下:

1. 确定数据结构

首先需要确定数据结构,可以使用字典来表示家族树,key为成员名字,value为成员对象,其中成员对象包括成员的父亲、母亲、配偶等信息。

2. 构建成员对象

需要构建成员对象,包括成员的名字、性别、父亲母亲、配偶等信息。类似下面的代码可以实现成员对象的构建:

class Member:
    def __init__(self, name, gender, father=None, mother=None, spouse=None):
        self.name = name
        self.gender = gender
        self.father = father
        self.mother = mother
        self.spouse = spouse
        self.children = []

其中,通过father、mother、spouse和children来表示成员之间的关系。

3. 构建家族树

通过读取输入的数据,可以构建家族树。可以采用深度优先遍历的方式来构建,具体实现可以参考下面的代码:

def build_family_tree(data):
    family_tree = {}
    for line in data:
        name, gender, parent = line.split(',')
        if name not in family_tree:
            family_tree[name] = Member(name, gender)
        if parent != '-':
            if parent not in family_tree:
                family_tree[parent] = Member(parent, 'M' if gender == 'F' else 'F')
            if gender == 'M':
                family_tree[parent].children.append(family_tree[name])
                family_tree[name].father = family_tree[parent]
            else:
                family_tree[parent].children.append(family_tree[name])
                family_tree[name].mother = family_tree[parent]
    return family_tree

4. 计算亲戚关系

有了家族树,就可以实现计算亲戚关系的功能。根据输入的两个名字,采用深度优先搜索的方式找到它们的最近公共祖先,然后根据路径长度来计算它们的亲戚关系。具体实现可以参考下面的代码:

def find_relationship(family_tree, name1, name2):
    member1 = family_tree[name1]
    member2 = family_tree[name2]
    ancestor = None
    visited = set()

    def dfs(member):
        visited.add(member.name)
        if member.father:
            if member.father.name in visited:
                nonlocal ancestor
                ancestor = member.father
                return
            dfs(member.father)
        if member.mother:
            if member.mother.name in visited:
                nonlocal ancestor
                ancestor = member.mother
                return
            dfs(member.mother)

    dfs(member1)
    path1 = get_path(member1, ancestor)
    path2 = get_path(member2, ancestor)

    if len(path1) > len(path2):
        path1, path2 = path2, path1

    if len(path1) == 1 and len(path2) == 1:
        return 'SIBLINGS' if member1.gender == member2.gender else 'COUSINS'

    path1_length = len(path1) - 1
    path2_length = len(path2) - 1

    if path1_length == path2_length:
        return 'SIBLINGS-IN-LAW' if member1.gender == member2.gender else 'COUSINS-IN-LAW'

    if path1_length < path2_length:
        path1.append('PARENT')
        return get_relationship(path1_length+1, path2_length, path2[-1], member2.gender)
    else:
        path2.append('CHILD')
        return get_relationship(path2_length+1, path1_length, path1[-1], member1.gender)

示例说明

假设有如下测试数据:

data = [
    'Bob,M,-',
    'Jenny,F,-',
    'Tom,M,Bob,Jenny',
    'Mary,F,Bob,Jenny',
    'John,M,Tom,Mary',
    'Lynn,F,Tom,Mary'
]

其中,第一列是成员名字,第二列是性别,“-”表示父母或配偶信息未知。可以通过调用build_family_tree函数构建家族树:

family_tree = build_family_tree(data)

然后可以通过调用find_relationship函数计算亲戚关系,例如:

result = find_relationship(family_tree, 'John', 'Lynn')
print(result)

输出结果为:

COUSINS-IN-LAW

又例如:

result = find_relationship(family_tree, 'Tom', 'Mary')
print(result)

输出结果为:

SIBLINGS