积分431 / 贡献0

提问31答案被采纳5文章47

[经验分享] 亲戚关系计算器三方库发布啦 原创

润开鸿_坚果 显示全部楼层 发表于 2024-1-31 08:32:11

亲戚关系计算器

一、下载安装

ohpm install @nutpi/relationship

OpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包

二、使用

import relationship from "@nutpi/relationship"

参数 options结构为:

var options = {
    text:'',        // 目标对象:目标对象的称谓汉字表达,称谓间用‘的’字分隔
    target:'',          // 相对对象:相对对象的称谓汉字表达,称谓间用‘的’字分隔,空表示自己
    sex:-1,         // 本人性别:0表示女性,1表示男性
    type:'default',     // 转换类型:'default'计算称谓,'chain'计算关系链,'pair'计算关系合称
    reverse:false,      // 称呼方式:true对方称呼我,false我称呼对方
    mode:'default',     // 模式选择:使用setMode方法定制不同地区模式,在此选择自定义模式
    optimal:false,          // 最短关系:计算两者之间的最短关系
};

代码示例:

// 如:我应该叫外婆的哥哥什么?
relationship({text:'妈妈的妈妈的哥哥'});
// => ['舅外公']

// 如:七舅姥爷应该叫我什么?
relationship({text:'七舅姥爷',reverse:true,sex:1});
// => ['甥外孙']

// 如:舅公是什么亲戚
relationship({text:'舅公',type:'chain'});
// => ['爸爸的妈妈的兄弟', '妈妈的妈妈的兄弟', '老公的妈妈的兄弟']

// 如:舅妈如何称呼外婆?
relationship({text:'外婆',target:'舅妈',sex:1});
// => ['婆婆']

// 如:外婆和奶奶之间是什么关系?
relationship({text:'外婆',target:'奶奶',type:'pair'});
// => ['儿女亲家']

三、背景

亲属是基于婚姻、血缘和法律拟制而形成的社会关系。亲属关系包括夫妻、父母、子女、兄弟姊妹、祖父母和外祖父母、孙子女和外孙子女、儿媳和公婆、女婿和岳父母、以及其他三代以内的旁系血亲,如伯、叔、姑、舅、姨、侄子女、甥子女、堂兄弟姊妹、表兄弟姊妹、姨兄弟姊妹等。

亲属称谓指是以本人为中心确定亲族成员和本人关系的名称,是基于血亲姻亲基础上的亲属之间相互称呼的名称、叫法。汉族的家族亲属关系条理分明尊卑有序:比自己长一辈的称呼有姨姑舅叔伯,同辈的有兄弟姊妹、堂表亲等等,下一辈有甥侄等等。中国人由于姻亲而产生的亲戚关系相当庞杂,“祖宗十八代”、“五服”、“六亲”、“九族”让人难以区分,其派生出的各种称谓也是中华文化的一大特征。

如今由于工作生活节奏差异,很多关系稍疏远的亲戚之间来往并不多,年龄差异长幼辈分模糊。春节拜年走亲戚遇到七大姑八大姨,往往会搞不清楚哪位亲戚应该喊什么称呼,很是尴尬。不仅小孩搞不清亲戚关系和亲戚称谓,就连年轻一代的大人也都常常模糊混乱。

“中国亲戚关系计算器”为你避免了叫错、不会叫亲戚的尴尬,收录了中国亲戚关系称呼大全,只需简单的输入即可完成称呼计算。称呼计算器同时兼容了不同地域的方言叫法,你可以称呼父亲为:“老爸”、“爹地”、“老爷子”等等。让您准确的叫出亲戚称谓,理清亲属之间的亲戚关系,轻松掌握中国式的亲戚关系换算,让你更了解中国文化。

四、功能支持

  • 1. 使用别称查询:

    姥姥的爸爸的老窦 = 外曾外曾祖父

    娘子的爹地的母亲 = 祖岳母

    岳丈的妈咪的细佬 = 舅祖岳父

  • 2. 使用合称查询:

    姐夫的双亲 = 姊妹姻父 / 姊妹姻母

    妈妈的祖父母 = 外曾祖父 / 外曾祖母

    弟弟的孩子 = 侄子 / 侄女

  • 3. 大小数字混合查询:

    大哥的二姑妈的七舅姥爷 = 舅曾外祖父

    二女婿的小姨 = 女姻姨妹

    大佬的三叔的次子 = 堂哥 / 堂弟

  • 4. 不限制祖辈孙辈跨度查询:

    舅妈的婆婆的外甥的姨妈的侄子 = 舅表舅父

    老公的丈母娘的儿媳 = 嫂子 / 弟妹

    外婆的孙子的爸爸的仔 = 舅表哥 / 舅表弟

  • 5. 根据年龄推导可能性:

    哥哥的表姐 = 姑表姐 / 舅表姐

    堂妹的姐姐 = 堂姐 / 堂妹

    弟弟的表哥 = 姑表哥 / 姑表弟 / 舅表哥 / 舅表弟

  • 6. 根据语境确认性别:

    老婆的女儿的外婆 = 岳母

    爱人的婆婆的儿子 = 哥哥 / 弟弟 / 自己

    岳母的配偶的儿子的爸爸 = 岳父

  • 7. 支持古文式表达:

    吾父之舅父 = 舅爷爷

    母之兄长之妻 = 大舅妈

    泰山之高堂 = 祖岳父 / 祖岳母

  • 8. 解析某称谓关系链:

    七舅姥爷 = 妈妈的妈妈的兄弟

    姑奶奶 = 爸爸的爸爸的姐妹

    外太公 = 妈妈的爸爸的爸爸

  • 9. 算两个亲戚间的合称关系:

    奶奶 + 外婆 = 儿女亲家

    妈妈 + 婶婶 = 妯娌

    岳父 + 我 = 翁婿

五、关于分歧

一些称呼存在南北方或地区差异,容易引起歧义,并不保证和你所处地区的称谓习惯一致。

部分称呼有多种关系且跨辈分。例如:

  • 大爷:爷爷的哥哥 / 父亲的哥哥(北方);
  • 舅公:爸妈的舅舅 / 老公的舅舅;
  • 伯公:爸妈的伯父 / 老公的伯父;
  • 叔公:爸妈的叔叔 / 老公的叔叔;
  • 姨公:爸妈的姨丈 / 老公的姨丈;
  • 姨夫:姨妈的老公 / 姨子的老公;
  • 姑夫:姑妈的老公 / 姑子的老公;
  • 婶子:叔叔的老婆 / 叔子的老婆;
  • 妗子:舅舅的老婆 / 舅子的老婆;

部分称呼以现代生活常见理解为主。例如:

  • 媳妇:在古代或者北方地区指儿子的妻子,这里指自己的妻子(儿媳妇写作“息妇”);
  • 太太:一些地方指年长的妇人或曾祖父母,这里指自己的妻子;

六、常见问题

市面上同类型的算法基本以 “称谓-直接关系-称谓” 的方式实现,如:

"爸爸": {
    "爸爸": "爷爷",
    "妈妈": "奶奶",
    "哥哥": "伯父",
    "弟弟": "叔叔",
    "姐姐": "姑妈",
    "妹妹": "姑妈",
    "丈夫": "未知",
    "妻子": "妈妈",
    "儿子": {"older": "哥哥", 'middle': "我", "younger": "弟弟"},
    "女儿": {"older": "姐姐", 'middle': "我", "younger": "妹妹"}
}

这样的结构主要有以下问题:

  1. 无法跨代直接查询,如:如何知道“舅妈的婆婆”是谁?
  2. 无法逆向查询称谓,如:“表哥的妈妈”的妈妈是“舅妈”、“姨妈”还是“姑妈”?
  3. 数据结构过于臃肿, 如:某个节点下可能会出现多个“未知”
  4. 无法兼容多种称呼,如:各地称呼不尽相同,“爸爸”也可以叫“父亲”、“爹地”
  5. 无法进行关系拓扑,如:“舅妈”和我什么关系?

七、本算法的原理

采用 “关系链-称谓集合” 哈希对的方式建立数据库,映射亲戚网络中的每个节点和自己的关系

数据结构

'h':['老公','丈夫','先生','官人','男人','汉子','夫','夫君','相公','夫婿','爱人','老伴'],
'h,f':['公公','翁亲','老公公'],

每个称谓都可以找到相应的关系链,每个关系链同时有对应的称谓集合,这里需要引入自己“发明”的特殊语法标记

语法说明

【关系】f:父,m:母,h:夫,w:妻,s:子,d:女,xb:兄弟,ob:兄,lb:弟,xs:姐妹,os:姐,ls:妹
【修饰符】 1:男性,0:女性,&o:年长,&l:年幼,#:隔断,[a|b]:并列

例如:

"f"对应着爸爸,那么:"f,m"对应着奶奶,"f,f"对应着爷爷;

这样在查询关系的时候,只需要对关系链进行计算就好了,而不是对称谓进行字典查找

算法思路

  1. 当用户输入“舅妈的婆婆”,可以分解出两个对象“舅妈”和“婆婆”(前者的婆婆)
  2. 从“关系链-称谓集合”映射关系可知,这两个对象的关系链分别是:"m,xb,w"和"h,m",合并后的关系即:"m,xb,w,h,m"
  3. 此时关系链会出现冗余,需要进一步处理:
    • "w,h"表示“老婆的老公”,即自己,可直接将关系链简化成:"m,xb,m"
    • 同理,"xb,m"表示“兄弟的妈妈”,即自己的妈妈,可将关系链再次简化为:"m,m"
    • 当无法进一步简化时,就得到了“最简关系链”,将其带入亲戚关系数据库查询,便可知"m,m"即为自己的“外婆”
  4. 这样就将复杂的关系链转换成直接关系了,除此之外还可根据“关系链-称谓集合”反向通过称呼找到关系;

实现细节

  1. 如何实现关系链的简化?

    关系链为字符串,用正则表达式即可按情形匹配,同时做到“替换”的操作。由于所有非直接的关系,都是存在关系链表达的冗余。虽然冗余可能多层且复杂,只需要考虑两层关系中的去冗余,反复处理即可。

  2. 某些多层关系可能未必对应一种关系,如何解决关系的不唯一?

    “爸爸的儿子”不一定是自己,也可能是自己的兄弟。在语法中引入了“隔断”和“并列”语法,可以借助正则表达式将此类不唯一的关系拆分为多组,每次再单独带入递归求最简解即可。

  3. 每个节点离自己远一层关系,节点数据便翻倍,如何解决数据量过大的问题?

    中国的亲戚关系存在一定规律,旁系分支大体由 分支节点 及其 子代关系 ,我们只需记录 分支节点子代关系 即可。如:“舅表哥”和“堂哥”两者在和自己的关系链上存在一定相似,没必要记录两者所有关系。只需知道“舅表哥”是“舅舅”的后代,而“堂哥”是“叔伯”的后代,那么“舅表哥”和“堂哥”的所有后代及姻亲数据可以只存3部分。即:

    舅表哥关系数据 = 舅舅(分支节点) + 哥哥关系数据(子代关系);

    堂哥关系数据 = 叔伯(分支节点) + 哥哥关系数据(子代关系);

    这样的关系有很多,如:“舅表”、“姑表”、“从堂”、“姑表叔表”等等,对关系数据进行拆分复用,即可以达到压缩数据量。同时在脚本运行中对 分支节点子代关系 进行拼接即可组合出数据库。

八、开源协议

本项目基于 Apache ,请自由地享受和参与开源。感谢mumuy。和金陵科技学院的同学做出的努力

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

精彩评论1

houdashuai520

沙发 发表于 2024-2-27 15:18:35
哈哈哈,这个很有趣,再也不需要问父母,就能自己梳理出关系了

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部