*/
* Copyright (c) 2016,烟台大学计算机与控制工程学院
* All rights reserved.
* 文件名:test.cpp
* 作者:常轩
* 微信公众号:Worldhello
* 完成日期:2016年12月27日
* 版本号:V1.0
* 程序输入:无
* 程序输出:见运行结果
*/
/*
使用孩子兄弟结构进行存储
*/
#include<iostream>
#include<stdio.h>
#include<String>
#define MaxSize 1000
using namespace std;
char zuxian[100],chengyuan[100],fubei[100];
int zuigaomax=1;
int time=0;
typedef struct
{
char data[MaxSize]; //存放字符串
int length; //存放串长
}SqString;
struct Tree
{
char name[100];
char sex[100];
char fed[100];//配偶
char thing[1000];//个人简介
char borth[100];//生日
int level;//辈分
struct Tree *child; //孩子指针
struct Tree *brother; //兄弟指针
struct Tree *parent; //父亲指针
};
Tree *Create(Tree *t,char s[])
{ //创建族谱
Tree *p;
p=new Tree;
strcpy(p->name,s); //祖先名字
p->brother=NULL; //规定祖先只有一个人,即指向兄弟的指针为空,指向父亲节点的指针为空
p->child=NULL; //暂且将孩子指针赋值为空
p->parent=NULL;
p->level=1; //记录辈分,为第一代
cout<<"请输入性别:"<<endl;
cin>>p->sex;
cout<<"请输入配偶名称:"<<endl;
cin>>p->fed;
cout<<"请输入生日:"<<endl;
cin>>p->borth;
cout<<"请输入个人简介:"<<endl;
cin>>p->thing;
t=p;
return t; //创建祖先成功,返回
}
Tree *Find(Tree *b,char cname[]) //查询位置
{
Tree *p;
if(b==NULL) //如果树为空,则返回NULL
return NULL;
else
if(strcmp(b->name,cname)==0) //判断查询的是否为祖先节点
{
return b;
}
else //如果不符合上面的两种情况,则使用递归进行下一轮查询
{
p=Find(b->child,cname);
if(p!=NULL)
{
return p;
}
else
{
return Find(b->brother,cname);
}
}
}
void coutxinxi(Tree *b,char cname[]) //输出个人信息
{
Tree *p;
p=Find(b,cname); //使用查询位置函数,对所要查询的成员信息进行定位,然后再返回赋值给p
cout<<"名字:\t"<<p->name;
cout<<"第"<<p->level<<"代";
cout<<"父辈:\t"<<p->parent->name;
cout<<"性别:\t"<<p->sex;
cout<<"配偶:\t"<<p->fed;
cout<<"生日:\t"<<p->borth;
cout<<"个人简介:\t"<<p->thing;
}
int chaxunbeifen(Tree *b,char chaxunmingzi[]) //查询名称的辈分
{
Tree *p;
p=Find(b,chaxunmingzi); //首先找到这个人,因为节点信息里包括了成员的辈分信息,所以如果此节点不为空就直接返回p->level
if(p==NULL)
return 0;
else
return p->level;
}
void add(Tree *b,char parent[],char erzi[]) //增加
{
Tree *p,*q;
p=Find(b,parent); //根据输入的父亲节点的名字,进行查找父亲节点
if(p==NULL) //为空,不存在
{
cout<<"双亲不存在"<<endl;
return ;
}
q=new Tree; //存在,对子节点进行赋值
strcpy(q->name,erzi);
q->level=p->level+1; //辈分在父亲结点的基础上进行+1
cout<<"请输入性别:"<<endl;
cin>>chengyuan;
strcpy(q->sex,chengyuan);
cout<<"请输入配偶名称:"<<endl;
cin>>chengyuan;
strcpy(q->fed,chengyuan);
cout<<"请输入生日:"<<endl;
cin>>chengyuan;
strcpy(q->borth,chengyuan);
cout<<"请输入个人简介:"<<endl;
cin>>chengyuan;
strcpy(q->thing,chengyuan);
if(p->level+1>zuigaomax) //判断一下,新增的这个节点的辈分是否超过了整个族谱的高度,如果超过则纪录最高长度的变量zuigaomax=此时的辈分+1
{
zuigaomax=p->level+1;
}
q->child=NULL; //接着对其孩子指针赋值为空
q->brother=NULL; //兄弟指针赋值为空
q->parent=p; //父亲结点就是此函数刚开始时的查找到的,然后进行赋值
if(p->child==NULL) //现在开始查找一下新增节点的父节点原来有没有孩子,如果没有,就直接将父节点的孩子指针直接指向次新增节点
{
p->child=q;
}
else //如果有孩子,则开始循环,知道查到父节点的最后一个新增的孩子节点
{
p=p->child;
while(p->brother!=NULL)
{
p=p->brother;
}
p->brother=q; //将新增的节点与查找到的最后一个孩子节点连接起来
}
}
void xiugai(Tree *b,char chaxunmingzi[]) //修改函数
{
Tree *p;
p=Find(b,chaxunmingzi); //查找要修改的节点
if(p==NULL) //没查到,返回NULL
{
cout<<"查无此人";
return ;
}
cout<<"请输入修改信息"<<endl; //查到之后进行逐项修改
cout<<"新姓名:";
cin>>chengyuan;
strcpy(p->name,chengyuan);
cout<<"请输入性别:"<<endl;
cin>>chengyuan;
strcpy(p->sex,chengyuan);
cout<<"请输入配偶名称:"<<endl;
cin>>chengyuan;
strcpy(p->fed,chengyuan);
cout<<"请输入生日----(格式:****--**--**)"<<endl;
cin>>chengyuan;
strcpy(p->borth,chengyuan);
cout<<"请输入个人简介:"<<endl;
cin>>chengyuan;
strcpy(p->thing,chengyuan);
}
void deletechengyan(Tree * &b,char chaxunmingzi[]) //删除函数
{
Tree *p,*shanchus;
p=Find(b,chaxunmingzi);
if(p==NULL)
{
cout<<"此人不存在"<<endl;
return ;
}
shanchus=p;
Tree *q;
q=p->parent;
if(q==NULL) //如果被删除节点是第一个,则释放
{
delete shanchus;
}
else if(q->child==p) //判断被删除节点是否是父节点直接指向的节点
{
if(p->brother!=NULL)
{
q->child=p->brother;
}
delete shanchus;
}
else
{
Tree *r=q->child,*m;
m=r;
while(r!=NULL)
{
if(r==shanchus)
{
m->brother=r->brother;
delete shanchus;
break;
}
m=r;
r=r->brother;
}
}
}
void bianli(Tree *b) //遍历 查看族谱
{
if (b!=NULL)
{
for(int i=0;i<b->level;i++)
cout<<" ";
cout <<"第"<<b->level<<"代";
cout <<b->name<<"---";
cout<<"配偶:"<<b->fed<<"---";
cout<<"出生日期:"<<b->borth<<endl;
if (b->child!=NULL || b->brother!=NULL)
{
bianli(b->child);
bianli(b->brother);
}
}
}
void creatZupu(Tree * &u) //创建族谱
{
cout<<"开始创建族谱!作为祖先很光荣啊!"<<endl;
cout<<"请输入祖先姓名:"<<endl;
cin>>zuxian;
u=Create(u,zuxian);
cout<<"好了,恭喜啦!第一个祖先已经入住族谱了,后辈们要加油哟!"<<endl;
}
SqString changeSign(char sign[]) //将字符串转换成串存储结构
{
int i;
SqString str;
for(i=0;sign[i]!='\0';i++)
{
str.data[i]=sign[i];
}
str.length=i;
return str;
}
bool piPei(SqString s,SqString t) //BF算法 串的模式皮匹配
{
int i=0,j=0;
while(i<s.length&&j<t.length)
{
if(s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和字串依次匹配下一个节点
j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=t.length)
return true;// (i-t.length);下标
else
return false;
}
void bianli1(Tree *b, char aboutInformation[]) //遍历搜索
{
if(b!=NULL)
{
if(piPei(changeSign(b->thing),changeSign(aboutInformation))==true) //调用pipei()函数对于每一个节点的简历和关键字进行匹配,如果简历中包含关键字则输出成员姓名和成员的相关简历
{
cout<<"名字:\t"<<b->name<<endl<<endl;
cout<<"\t——相关介绍:"<<endl<<"\t"<<b->thing<<endl;
}
if (b->child!=NULL || b->brother!=NULL) //进行递归调用,遍历每一个节点的个人简历
{
bianli1(b->child,aboutInformation);
bianli1(b->brother,aboutInformation);
}
}
// else
// cout<<"尚未创建族谱!"<<endl;
}
void seven(Tree * u) //根据关键字查询
{
cout<<"请输入有关信息:"<<endl;
char aboutInformation[80];
cin>>aboutInformation;
bianli1(u,aboutInformation); //将关键字传入进行遍历搜索
}
int menu_select();
int main()
{
Tree *u;
u=NULL;
// SqString *s,*t;
int n;.
while(1)
{
n=menu_select();
if(n==1)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
cout<<"请输入添加成员名称:"<<endl;
cin>>chengyuan;
cout<<"请输入添加成员的长辈名称:"<<endl;
cin>>fubei;
add(u,fubei,chengyuan);
}
else if(n==2)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
cout<<"请输入删除成员的名称:"<<endl;
char chengyuan[10];
cin>>chengyuan;
deletechengyan(u,chengyuan);
}
else if(n==3)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
cout<<"请输入查询名称:"; cin>>chengyuan;
Tree *o=Find(u,chengyuan);
if(o)
{
cout<<"名字:\t"<<o->name<<endl;
cout<<"辈分:\t"<<o->level<<endl;
cout<<"性别:\t"<<o->sex<<endl;
cout<<"配偶:\t"<<o->fed<<endl;
cout<<"生日:\t"<<o->borth<<endl;
cout<<"个人简介:\t"<<o->thing<<endl;
if(o->parent==NULL)
{
}
else
cout<<"爸爸为"<<o->parent->name<<endl;
}
else
{
cout<<"查无此人"<<endl; }
}
else if(n==4)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
bianli(u);
}
else if(n==5)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
cout<<"请输入查询名称:"; cin>>chengyuan;
int y=chaxunbeifen(u,chengyuan);
if(y)
{
cout<<"辈分为:第"<<y<<"代"<<endl;
}
else
{
cout<<"查无此人"<<endl;
}
}
else if(n==6)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
cout<<"请输入要修改的成员名称"<<endl;
cin>>chengyuan;
xiugai(u,chengyuan);
}
else if(n==7)
{
if(u==NULL)
{
cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl;
continue;
}
seven(u);
}
else if(n==8)
{
creatZupu(u);
}
else
{
break;
}
}
return 0;
}
int menu_select() //菜单函数定义
{
char c;
printf("===============================================================\n");
printf("|--------------------家族成员信息管理系统 v1.0----------------|\n");
printf("| |\n");
printf("| 1.添加成员 |\n");
printf("| 2.删除成员 |\n");
printf("| 3.查询个人信息 |\n");
printf("| 4.查看族谱 |\n");
printf("| 5.查询辈分 |\n");
printf("| 6.修改信息 |\n");
printf("| 7.根据关键字查询 |\n");
printf("| 8.创建族谱 |\n");
printf("| 9.退出系统 |\n");
printf("***************************************************************\n");
printf(" 请输入(1-7)进行操作:\n");
do{
scanf("%c",&c);
}while(c<'1'||c>'9');
return c-48;
}