《亲属核算器》大概是我迄今为止写过最杂乱的算法了,它或许看起来它好像逻辑简略,仅1个办法调用罢了,却耗费了我很多的时刻!从一开端灵光乍现,想到完成它的开端思路,到现在开源已7年多了。这期间,我一直在不断更新才让它日趋完善,它的作业不仅是对数据的整理,还有我对程序逻辑的梳理和规划思路的琢磨。

假如你也对传统文化略微有点兴趣,不妨耐性的看下去……也许你会发现:原理我们日常习以为常的一个称号,需求考虑那么多细节。

称谓体系的巨大

中国的亲属称号体系杂乱在于,它对每种亲属联络都有特定的称号,一起关于同种联络不同地方、关于不同性别的人都或许有不同的称号。

  1. 对外国人而言,爸爸妈妈的兄弟姐妹不外乎:uncle、aunt;而关于我们来说,爸爸妈妈的兄弟姐妹有:伯父、叔叔、姑姑、舅舅、阿姨;

  2. 不同地方对同个亲属的称号都是不一样的,以爸爸为例,别称包括有:爸爸、父亲、老爸、阿爸、老窦、爹地、老汉、老爷子等等;

  3. 不同联络链或许具有相同的称号;比方“舅公”一词,可所以爸爸妈妈亲的舅舅,也可所以老公的舅舅,而这两种联络辈分却不同。究其原因我猜想是,传统上由姻亲发生的亲属联络,为表达谦卑会自降一辈,随子女称号配偶的长辈。

  4. 一个称号中或许是多种联络的合称。比方:“爸爸妈妈”、“子女”、“公婆”,他们不是指代一个人物联络,而是几个联络的合称。

在规划这套算法的时候,我希望它能尽量包括各种称号、各种联络链,由于我之所以做这个项目便是像让它真实集合多种需求,否则假如它不行全面那终究是个代码演示罢了。

联络网络的表达

亲属的联络网络是以血缘和婚姻为枢纽联络在一起的,每个节点都是一个人,每个人都有诸如:父、母、兄、弟、姐、妹、子、女、夫、妻这样的基础联络。联络网络中的节点数量随着层级的加深而指数增加!假如是5层联络,大概就有9x9x9x9x9 = 59049种联络了(当然,这其间有小部分是重复的)。假如想要把几万个联络,数十万个称号悉数尽收其间显然是不或许的,没人有那个精力去维护。

迄今为止我写过最复杂的算法

怎么将亲属联络网络中每个节点之间的联络用数据结构表现出来是一个难点。它需求确保数据量尽量全、占用体积小、易检索、可扩展等特点,这样才能确保算法检索联络时的完整性和高效性。

网络的寻址问题

已然是核算,那一定不是简略经过父、母、子、女等这些基础联络找对应称号了。否则这便是简略的字典查询罢了,谈不上算法。假如问的是:“舅妈的儿子的奶奶的外孙”又该怎么呢?首要,需求在网络中找到单一称号,如“舅妈”,而下一步找她的“儿子”,而非你自己的“儿子”。这就要求有类似于指针的功用,联络链每往前走一步,指针就指引着联络的节点,终究需找到答案。

而就像前面提到的一样,某些称谓或许对应多条联络,一起有些联络并不是唯一的。比方说你爸爸的儿子便是你吗?有没有或许是弟弟或者哥哥?而这些是不是一起取决于你的性别呢? 由于假如你是女的,那么你爸爸的儿子必定不是你呀!

这就对算法提出了一个要求,它有必要准确的包括多种或许性。

迄今为止我写过最复杂的算法

年纪和性别的估测

随着联络链的杂乱,终究得到的答案也有多种。那有没有一种或许,在对联络链的描绘中是否存在一些词,可以经过逻辑判别知道对方的性别或年纪大小,进而扫除一些不可呢?

例如“爱人的婆婆的儿子”,单从“爱人”二字我们并不能估测自己的性别,然后的“婆婆”确是只要女人才有的亲属,“爱人的婆婆”就足以揣度自己是男的,那么“爱人的婆婆的儿子”必定包括自己。相反,“爱人的婆婆的女儿”一定不是自己,只能是自己的姊妹。

迄今为止我写过最复杂的算法
迄今为止我写过最复杂的算法

再比方:自己哥哥的表哥也是你的表哥,你弟弟的表哥还是你表哥吗?由于你无法判别你弟弟和他的表哥谁大,天然无法判别对方是你的表哥还是表弟。已然都有或许存在,就需求保存或许性进一步核算。这就触及到了在联络链的核算中不仅仅需求考虑隐藏的性别头绪,还有年纪头绪。

迄今为止我写过最复杂的算法
迄今为止我写过最复杂的算法

身份视点的切换

单从亲属和自己的联络链条中开端算亲属的称号,仅仅是单向的计算,只需求一个个联络往下算就好。假如想知道对方称号为我什么,这就需求站在对方的视点,从头逆向的调理出我和他之间的联络了。比方我的“外孙”应该叫我什么?

迄今为止我写过最复杂的算法

另一方面,假如把我置身于第三者,想知道我的两个亲属他们之间怎么称号,就有必要要一起站在两个亲属的视点,看待他们彼此之间的联络了。比方:我的“舅妈”该叫我的“外婆”什么呢?

迄今为止我写过最复杂的算法

年纪排序的问题

前面提到的都是对不同联络链中的或许性琢磨,那假如相同的联络怎么判别年纪呢?假如你有3个舅舅呢?尽管不管哪个舅舅,他们关于你的联络都一样,他们的老婆你都得叫声“舅妈”。但他们毕竟有年纪区别,天然就有长幼的排序了。有了排序,就又引发了对他们之间联络的考虑。

还是举例说明下:“舅舅”和“舅妈”是什么联络?信任大部分榜首反响便是夫妻联络呗!其实不尽然,毕竟有些人不会只要一个舅舅吧?那“大舅妈”和“二舅”就不是夫妻联络了,他们是叔嫂联络呀。“二舅”得管“大舅妈”叫“嫂子”,“大舅妈”得管“二舅”叫“小叔子”。

迄今为止我写过最复杂的算法
迄今为止我写过最复杂的算法

再进一步说,“二舅的儿子”得叫“大舅妈”为“伯母”,“大舅的儿子”得叫“二舅”为“二叔”。这些由父辈的排序问题影响自己称谓的不同,而是我这套算法需求考虑的内容。

迄今为止我写过最复杂的算法
迄今为止我写过最复杂的算法

怎么样?是不是没有想象中的那么简略? 假如你想了解更多完成和思路的细节,可以关注本项目开源代码哦:github.com/mumuy/relat…

你也可以在此了解算法的基础原理:算法完成原理介绍