每年春节都会有一些亲戚,我几乎没有印象,但是他们的父母很熟悉,关系很乱,你不能甚至告诉。今年春节在家无所事事。刚知道有中文亲属关系计算器,想自己实现。特此记录。算法实现及介绍由于本人能力有限,只完成了基本功能....需求亲缘链计算得到的结果应该叫什么数据定义关系字符和修饰符的定义[Relationship]f:parent,m:mother,h:husband,w:wife,s:son,d:female,xb:brother,ob:brother,lb:brother,xs:sister,os:sister,ls:sister[修饰符]&o:older,&l:young,#:partition,[a|b]:并列关系对应的数据集,关系过滤数据集(data.json和filter.json)作者的关系过滤数据集json有问题,所以改了filterdata集合的目的:比如m,h是我妈的老公是我爸,也就是f。filter的作用是去重和简化。需要将exp换成str来实现算法。基本上有三种情况需要解决:我父亲=父亲,我弟弟的弟弟=我/兄弟/兄弟,我兄弟的丈夫=?分析三种结果:1.单一结果2.多结果3.错误提示,那么我们的算法必须兼容以上三种情况。让我们一步一步地实施它。算法主要函数一:transformTitleToKey这个函数主要负责将文本转化为关系符号#将文本转化为关系符号deftransformTitleToKey(text):result=text.replace("的",",").replace("I","").replace("爸爸","f").replace("父亲","f").replace("妈妈","m").replace("母亲","m").replace("爷爷","f,f").replace("奶奶","f,m").replace("爷爷","m,f").replace("爷爷","m,f")。replace("外婆","m,m").replace("外婆","m,m").replace("老公","h").replace("老公","h").replace("wife","w").replace("wife","h").replace("son","s").replace("daughter","d").replace("brother","xd").replace("brother","ob").replace("brother","lb").replace("sister","xs").replace("sister","os").replace("sister","ls").strip(",")returnresult这个简化了原参考作者的写法,比较简单(不是),符合计算器设置算法主要功能2:FilteHelper这个功能主要ly负责去重和简化#去重和简化defFilteHelper(text):result=textfilterName='/filter.json'#filter.json文件路径ifnotos.path.isfile(filterName):return"filterNamefiledoesnotexist"withopen(filterName,"r")asf:obj=list(ijson.items(f,'filter'))foriinrange(len(obj[0])):users=obj[0][我]['exp']ifusers==result:returnobj[0][i]['str']elifre.match(obj[0][i]['exp'],result):#matchregularresult1=re.findall(obj[0][i]['exp'],result)#以数组的形式返回string中所有匹配pattern的字符串print(result1)a=0result2=""iflen(result1)>1:尝试:foriinlen(result1):result=result.replace("$"+str(a+1),result1[a])a=a+1ifresult.find("#")!=-1:result_l=resultresultList=list(set(result_l.split("#")))##是分隔符,所以在resultList中为key拆分文本:result=FilteHelper(key.strip(","))if(result.find("#")==-1):#当关系符号不包含#时,将其添加到最终结果中result2=result2+resultreturnresult2else:returntextexceptExceptionase:returntextelse:returnstr(result1).replace("[\'","").replace("\']","")elifre.match(obj[0][i]['exp'],strInsert(result,0,',')):#符合常规result1=re.findall(obj[0][i]['exp'],strInsert(result,0,','))#返回string中所有匹配pattern的字符串,返回形式为数组a=0result2=""iflen(result1)>1:try:foriinlen(result1):result=结果.replace("$"+str(a+1),result1[a])a=a+1如果result.find("#")!=-1:result_l=resultresultList=list(set(result_l.split("#")))##是一个分隔符,所以拆分resultList中key的文本:result=FilteHelper(key.strip(","))if(result.find("#")==-1):#当关系符号不包含#时,添加到最终结果result2=result2+resultreturnresult2else:returntextexceptExceptionase:returntextelse:returnstr(result1).replace("[\'","").replace("\']","")returntext原参考作者这里的解释有点乱,所以我根据自己写出来的个人意见。。。能跑。。。如有错误,请指出个人测试单的结果。可以实现多种结果。建议实现多个结果。详细理解算法见输出和代码主要函数三:dataValueByKeys该函数主要负责从数据源中查找对应的keyResult#从数据源中查找key对应的结果defdataValueByKeys(data_text):if(isChinese(data_text)):#判断是否包含中文,其中包含特殊回复returndata_textdataName='/data.json'#data.json文件路径ifnotos.path.isfile(dataName):return"data文件不存在”fo=open(dataName,'r',encoding='utf-8')ID_Data=demjson.decode(fo.read())fo.close()try:ifID_Data[data_text]:cityID=ID_Data[data_text]text=""forkeyincityID:text=text+key+'\\'returntext.strip("\\")else:return"NotFound"除了Exceptionase:result=""resultList=FilteHelper(strInsert(data_text,0,',')).split(",")forkeyinresultList:result=result+dataValueByKeys(key)returnresult输出和效果基本达到效果一些细节和已知问题首先是性别:如果'我'是女性,那么'我父亲的儿子'可以是['兄弟','兄弟']而不是'我'(上面的代码没有实现)另外,关于夫妻关系:一般情况下,男性称呼只能有'wife',女性头衔只能有'husband'。(上面的代码已经实现了)三、多种可能:'我父亲的儿子'可以是['我','兄弟','兄弟'],如果是后面计算的,比如'我父亲的儿子''儿子',我们需要同时考虑'我儿子'、'兄弟的儿子'和'兄弟的儿子'这三种可能性。(以上代码已经实现)已知问题:与本人相关的多个问题中,部分源码可能仍然存在莫名其妙的BUG。欢迎来到Star━(`?′)ノ亻!(最新效果及更新修复BUG首先发布在github上,以github上列出的效果为准)github参考站在巨人肩膀上的hinese血缘系统。ChineseKinshipCalculator-FamilyAppellation/SalutationCalculation/KinshipAlgorithm算法主要参考这个KinshipCalculator
