这个题还算简单,其实如果真的要解决家谱的问题,就没有那么简单了(这个家谱问题,有时间我会实现,待定~~)
一、题目
三,找家谱成员
输入若干行,每一行的第一个输入为家谱中的某成员,该行接着输入的信息为每个孩子姓名。
最后一行的输入为要求查找的二个家谱成员的名字。
要求,根据输入的家谱成员信息,建立二叉树家谱关系图,并输出二位待查成员在家谱中的关系,
包括输出他们最近邻的共同祖先以及在家谱中相差的层次数。
eg1:
Input:
Ye Shu Ba
Shu Ge Mei1
Ba Self Mei2
Ge Son1 Son2
Son2 Mei1
Output:
Shu 1
eg2:
Input:
1 2 3
2 4 5
3 6 7
4 8 9
5 10 11
6 12 13
3 13
Output:
3 2
二、思路
1.把家谱存储到vector数组中,(省去:再构造二叉树,父节点 左孩子 右孩子-------这一步在真正的家谱问题中一定不能避免!)
2.找到最后两个名字的所有祖先(包括他们自己),存储到两个数组中,按照从子孙到祖先的顺序
3.比较两个数组的每一个元素,输出第一个相同的祖先,记下两个人跟祖先的数组下标差就是差的层次数
三、代码
#include <iostream> #include <string> #include <vector> using namespace std; struct Node{ int num; string name,l,r; }; /* void Create(Tree& T){ //string s; //getline(cin,s); T->num = i; i++; cin>>T->name; Node* N1 = new Node; Node* N2 = new Node; N1->parent = T; N2->parent = T; T->lChild = N1; T->rChild = N2; Create(N1); Create(N2); }*/ string Parent(vector<Node>& v,vector<string>& v1,const string name){//寻找这个名字的父亲,并返回 for(int i=0;i<v.size()-1;i++){ if(name == v[i].l || name == v[i].r){//判断这个名字是否和某一个节点的左、右孩子相等 v1.push_back(v[i].name);//第1,2,……个parent return Parent(v,v1,v[i].name); } } return "-1"; } void print(vector<string>& v){ for(int i=0;i<v.size();i++){ cout<<v[i]<<endl; } } void main(){ freopen("G:/17_3.txt","r",stdin); //1.把家谱存储到vector数组中,(省去:再构造二叉树,父节点 左孩子 右孩子) //2.找到最后两个名字的所有祖先(包括他们自己),存储到两个数组中,按照从子孙到祖先的顺序 //3.比较两个数组的每一个元素,输出第一个相同的祖先,记下两个人跟祖先的数组下标差就是差的层次数 /*Tree root = new Node; root->parent = NULL; Create(root);*/ vector<Node> v; int n=0;//表示总行数 while(!cin.eof()){ Node tem; tem.num = n; cin>>tem.name>>tem.l>>tem.r; v.push_back(tem); n++; } n-=1; vector<string> v1; vector<string> v2; v1.push_back(v[n].name);//第一个人的第0个parent,其实就是自己 v2.push_back(v[n].l);//第二个人的第0个parent,其实就是自己 Parent(v,v1,v[n].name); Parent(v,v2,v[n].l); /* print(v1); cout<<"+++++++++++++++"<<endl; print(v2); cout<<"+++++++++++++++"<<endl; */ for(int i=0;i<v1.size();i++){ for(int j=0;j<v2.size();j++){ if(v1[i] == v2[j]){ cout<<v1[i]<<" "; int t = i>j ? (i-j):(j-i); cout<<t<<endl; exit(0); } } } }