在家谱中查找关系远近
Posted tuoniao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在家谱中查找关系远近相关的知识,希望对你有一定的参考价值。
【问题描述】
同姓氏中国人见面常说的一句话是“我们五百年前可能是一家”。从当前目录下的文件in.txt中读入一家谱,从标准输入读入两个人的名字(两人的名字肯定会在家谱中出现),编程查找判断这两个人相差几辈,若同辈,还要查找两个人共同的最近祖先以及与他(她)们的关系远近。假设输入的家谱中每人最多有两个孩子,例如下图是根据输入形成的一个简单家谱:
通过该家谱,可以看到wangliang、wangguoping和wangguoan都有两个孩子,wangtian、wangxiang和wangsong有一个孩子,wangguang、wangqinian、wangping和wanglong还没有孩子。若要查找的两个人是wangqinian和wangguoan,从家谱中可以看出两人相差两辈;若要查找的两个人是wangping和wanglong,可以看出两人共同的最近祖先是wangguoan,和两人相差两辈。
【输入形式】
从当前目录下的in.txt中读入家谱。文件中第一行是家谱中有孩子的人数,后面每行内容是每个人的名字和其孩子的名字,名字都由1到20个英文字母构成,各名字间以一个空格分隔,整个家谱中的人员都不会重名;若只有一个孩子,则第二个孩子的名字为NULL;若没有孩子,则不需输入;输入的顺序是按照辈份从高到低依次输入,若孩子A出现在孩子B之前,则A的孩子应在B的孩子之前输入。假设以该形式读入的家谱肯定能够形成类似上图所示的一棵二叉树形式的家谱,家谱中任何两人相差的辈份不会超过100。
从标准输入读入要查找的两个人的名字,两名字间也以一个空格分隔。
【输出形式】
所有信息输出到标准输出上。
若要查找的两人不同辈,则先输出辈份低的名字,再输出辈份高的名字,然后输出相差几辈,都以一个空格分隔;
若两人同辈,按照两人名字从标准输入读取的先后顺序,分行输出两人的最近祖先名字、两人姓名以及相差几辈,各数据间以一个空格分隔。
【样例1输入】
假设当前目录下in.txt文件内容为:
6
wangliang wangguoping wangguoan
wangguoping wangtian wangguang
wangguoan wangxiang wangsong
wangtian wangqinian NULL
wangxiang wangping NULL
wangsong wanglong NULL
从标准输入读取:
wangqinian wangliang
【样例1输出】
wangqinian wangliang 3
【样例1说明】
家谱中输入了六个人名及其孩子的人名,形成了“问题描述”中的家谱,要查找的两人是wangqinian和wangliang,wangliang比wangqinian高3辈。
【样例2输入】
假设当前目录下in.txt文件内容为:
6
wangliang wangguoping wangguoan
wangguoping wangtian wangguang
wangguoan wangxiang wangsong
wangtian wangqinian NULL
wangxiang wangping NULL
wangsong wanglong NULL
从标准输入读取:
wangping wanglong
【样例2输出】
wangguoan wangping 2
wangguoan wanglong 2
【样例2说明】
和样例1同样输入了一家谱,wangping和wanglong共同的最近祖先是wangguoan,该祖先与两人相差两辈。
【题解】
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 struct family 6 { 7 char parent[25]; 8 char lchild[25]; 9 char rchild[25]; 10 }famList[300]; 11 12 struct FT 13 { 14 char name[25]; 15 int generation; 16 struct FT *parent; 17 struct FT *lchild; 18 struct FT *rchild; 19 }; 20 typedef struct FT famTree; 21 22 famTree *root=NULL; 23 char nochild[]="NULL"; 24 25 int read(FILE *fp); 26 int child(char name[]); 27 void insertTree(famTree *T,char lchild[],char rchild[]); 28 famTree *search(famTree *T,char name[]); 29 30 int main() 31 { 32 FILE *fp; 33 int num,i; 34 char name1[25],name2[25]; 35 famTree *p,*q,*r; 36 if((fp=fopen("in.txt","r"))==NULL) 37 exit(-1); 38 39 num=read(fp); 40 41 root=(famTree *)malloc(sizeof(famTree)); 42 strcpy(root->name,famList[0].parent); 43 root->generation=1; 44 45 r=(famTree *)malloc(sizeof(famTree)); 46 strcpy(r->name,famList[0].lchild); 47 r->generation=2; 48 r->parent=root; 49 r->lchild=r->rchild=NULL; 50 root->lchild=r; 51 if(child(famList[0].rchild)) 52 { 53 r=(famTree *)malloc(sizeof(famTree)); 54 strcpy(r->name,famList[0].rchild); 55 r->generation=2; 56 r->parent=root; 57 r->lchild=r->rchild=NULL; 58 root->rchild=r; 59 } 60 61 for(i=1;i<num;i++) 62 { 63 r=search(root,famList[i].parent); 64 insertTree(r,famList[i].lchild,famList[i].rchild); 65 } 66 67 scanf("%s %s",name1,name2); 68 p=search(root,name1); 69 q=search(root,name2); 70 if(p->generation<q->generation) 71 printf("%s %s %d ",name2,name1,q->generation-p->generation); 72 else if(p->generation>q->generation) 73 printf("%s %s %d ",name1,name2,p->generation-q->generation); 74 else 75 { 76 famTree *pParent,*qParent; 77 pParent=p; 78 qParent=q; 79 while(strcmp(pParent->name,qParent->name)!=0) 80 { 81 pParent=pParent->parent; 82 qParent=qParent->parent; 83 } 84 printf("%s %s %d ",pParent->name,name1,p->generation-pParent->generation); 85 printf("%s %s %d ",qParent->name,name2,q->generation-qParent->generation); 86 } 87 return 0; 88 } 89 90 int read(FILE *fp) 91 { 92 int n,i; 93 fscanf(fp,"%d",&n); 94 for(i=0;i<n;i++) 95 fscanf(fp,"%s %s %s",famList[i].parent,famList[i].lchild,famList[i].rchild); 96 fclose(fp); 97 return n; 98 } 99 int child(char name[]) 100 { 101 if(strcmp(name,nochild)==0) 102 return 0; 103 else 104 return 1; 105 } 106 void insertTree(famTree *T,char lchild[],char rchild[]) 107 { 108 famTree *p; 109 if(child(lchild)) 110 { 111 p=(famTree *)malloc(sizeof(famTree)); 112 strcpy(p->name,lchild); 113 p->generation=T->generation+1; 114 p->lchild=p->rchild=NULL; 115 p->parent=T; 116 T->lchild=p; 117 } 118 119 if(child(rchild)) 120 { 121 p=(famTree *)malloc(sizeof(famTree)); 122 strcpy(p->name,rchild); 123 p->generation=T->generation+1; 124 p->lchild=p->rchild=NULL; 125 p->parent=T; 126 T->rchild=p; 127 } 128 129 return; 130 } 131 famTree *search(famTree *T,char name[]) 132 { 133 famTree *p,*q; 134 p=T; 135 if(p==NULL) 136 return p; 137 else if(strcmp(p->name,name)==0) 138 return p; 139 else 140 { 141 q=search(p->lchild,name); 142 if(q==NULL) 143 return search(p->rchild,name); 144 else 145 return q; 146 } 147 }
以上是关于在家谱中查找关系远近的主要内容,如果未能解决你的问题,请参考以下文章