人类学研究对于家族很感兴趣,于是研究人员搜集了一些家族的家谱进行研究。实验中,使用计算机处理家谱。为了实现这个目的,研究人员将家谱转换为文本文件。下面为家谱文本文件的实例:
John
Robert
Frank
Andrew
Nancy
David
家谱文本文件中,每一行包含一个人的名字。第一行中的名字是这个家族最早的祖先。家谱仅包含最早祖先的后代,而他们的丈夫或妻子不出现在家谱中。每个人的子女比父母多缩进2个空格。以上述家谱文本文件为例,John这个家族最早的祖先,他有两个子女Robert和Nancy,Robert有两个子女Frank和Andrew,Nancy只有一个子女David。
在实验中,研究人员还收集了家庭文件,并提取了家谱中有关两个人关系的陈述语句。下面为家谱中关系的陈述语句实例:
John is the parent of Robert
Robert is a sibling of Nancy
David is a descendant of Robert
研究人员需要判断每个陈述语句是真还是假,请编写程序帮助研究人员判断。
输入格式:
输入首先给出2个正整数N(2≤N≤100)和M(≤100),其中N为家谱中名字的数量,M为家谱中陈述语句的数量,输入的每行不超过70个字符。
名字的字符串由不超过10个英文字母组成。在家谱中的第一行给出的名字前没有缩进空格。家谱中的其他名字至少缩进2个空格,即他们是家谱中最早祖先(第一行给出的名字)的后代,且如果家谱中一个名字前缩进k个空格,则下一行中名字至多缩进k+2个空格。
在一个家谱中同样的名字不会出现两次,且家谱中没有出现的名字不会出现在陈述语句中。每句陈述语句格式如下,其中X和Y为家谱中的不同名字:
X is a child of Y
X is the parent of Y
X is a sibling of Y
X is a descendant of Y
X is an ancestor of Y
输出格式:
对于测试用例中的每句陈述语句,在一行中输出True,如果陈述为真,或False,如果陈述为假。
输入样例:
6 5
John
Robert
Frank
Andrew
Nancy
David
Robert is a child of John
Robert is an ancestor of Andrew
Robert is a sibling of Nancy
Nancy is the parent of Frank
John is a descendant of Andrew
输出样例:
True
True
True
False
False
思想:确定每个人的父亲是谁,存入一个结构体中
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Name_Length 20
#define Sentence_Lenth 120
struct Node {
// 自己的名字
char Name[Name_Length];
// 父亲的名字
char Father[Name_Length];
// 自己名字前空白字符的个数
int BlankCount;
} People[Sentence_Lenth];
int main() {
int n, m;
char LocalName[Sentence_Lenth];
scanf("%d %d", &n, &m);
getchar();
for (int i = 0; i < n; i++) {
People[i].BlankCount = 0;
gets(LocalName);
int LName_Len = strlen(LocalName);
for (int j = 0; j < LName_Len; j++) {
if (LocalName[j] == ' ') {
People[i].BlankCount++;
} else {
strcpy(People[i].Name, LocalName + j);
break;
}
}
// 如果是没有空白字符的话,父亲就假设为NULL
if (!People[i].BlankCount) {
strcpy(People[i].Father, "NULL");
// 反之
} else {
for (int k = i - 1; k >= 0; k--) {
// 寻找第一个人的空白数比自己少的名字,就是父亲的名字
if (People[i].BlankCount > People[k].BlankCount) {
strcpy(People[i].Father, People[k].Name);
break;
}
}
}
}
char FrontName[Name_Length], Judge[Name_Length], BehindName[Name_Length],
Temp[Name_Length];
char LocalName1[Name_Length], LocalName2[Name_Length];
for (int i = 0; i < m; i++) {
scanf("%s %s %s %s %s %s", FrontName, Temp, Temp, Judge, Temp,
BehindName);
getchar();
//X is a child of Y
if (Judge[0] == 'c') {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, FrontName)) {
if (!strcmp(People[k].Father, BehindName)) {
printf("True\n");
} else {
printf("False\n");
}
break;
}
}
//X is the parent of Y
} else if (Judge[0] == 'p') {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, BehindName)) {
if (!strcmp(People[k].Father, FrontName)) {
printf("True\n");
} else {
printf("False\n");
}
break;
}
}
// X is a sibling of Y
} else if (Judge[0] == 's') {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, FrontName)) {
strcpy(LocalName1, People[k].Father);
}
if (!strcmp(People[k].Name, BehindName)) {
strcpy(LocalName2, People[k].Father);
}
}
if (!strcmp(LocalName1, LocalName2)) {
printf("True\n");
} else {
printf("False\n");
}
//X is a descendant of Y
} else if (Judge[0] == 'd') {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, FrontName)) {
strcpy(LocalName1, People[k].Father);
}
}
while (strcmp(LocalName1, BehindName) && strcmp(LocalName1, "NULL")) {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, LocalName1)) {
strcpy(LocalName1, People[k].Father);
}
}
}
if (!strcmp(LocalName1, "NULL")) {
printf("False\n");
} else {
printf("True\n");
}
//X is an ancestor of Y
} else if (Judge[0] == 'a') {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, BehindName)) {
strcpy(LocalName1, People[k].Father);
}
}
while (strcmp(LocalName1, FrontName) && strcmp(LocalName1, "NULL")) {
for (int k = 0; k < n; k++) {
if (!strcmp(People[k].Name, LocalName1)) {
strcpy(LocalName1, People[k].Father);
}
}
}
if (!strcmp(LocalName1, "NULL")) {
printf("False\n");
} else {
printf("True\n");
}
}
}
return 0;
}
但为啥下面这个代码不通过最后一个点呢????求助
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 2000
#define LOCALAUTO 100
char Relation[MAX][MAX];
int MapRelation[MAX];
char Sentence[MAX];
void getName(char Sentence[],char Front[],char Behind[]);
char *Trim(char a[]);
int main(){
int n,m;
scanf("%d %d",&n,&m);
getchar();
for(int i=0; i<n; i++){
gets(Relation[i]);
}
char Front[LOCALAUTO],Behind[LOCALAUTO];
for(int i=0; i<m; i++){
gets(Sentence);
getName(Sentence,Front,Behind);
int FrontPos=-1,BehindPos=-1;
for(int j=0; j<n; j++){
char *Get=Trim(Relation[j]);
if(FrontPos==-1 && strcmp(Get,Front)==0){
FrontPos=j;
}else if(BehindPos==-1 && strcmp(Get,Behind)==0){
BehindPos=j;
}
}
int FrontBlank=0,BehindBlank=0;
while(Relation[FrontPos][FrontBlank++]==' ');
while(Relation[BehindPos][BehindBlank++]==' ');
// X is a child of Y
if(strstr(Sentence,"child")){
if(FrontBlank>BehindBlank){
int flag=0;
while(FrontPos>=1){
int BlankTemp=0;
FrontPos--;
//孩子向后找父亲
while(Relation[FrontPos][BlankTemp++]==' ');
if(BehindBlank==BlankTemp){
if(FrontPos==BehindPos){
flag=1;
}
break;
}
}
if(flag){
printf("True\n");
}else{
printf("False\n");
}
}else{
printf("False\n");
}
// X is the parent of Y
}else if(strstr(Sentence,"parent")){
if(BehindBlank>FrontBlank){
int flag=0;
while(BehindPos>=1){
int BlankTemp=0;
BehindPos--;
//孩子向后找父亲
while(Relation[BehindPos][BlankTemp++]==' ');
if(FrontBlank==BlankTemp){
if(FrontPos==BehindPos){
flag=1;
}
break;
}
}
if(flag){
printf("True\n");
}else{
printf("False\n");
}
}else{
printf("False\n");
}
// X is a sibling of Y
}else if(strstr(Sentence,"sibling")){
if(strcmp(Front,Behind)==0){
printf("True\n");
}else if(FrontBlank==BehindBlank){
while(FrontPos>=1){
int FrontBlankCount=0;
FrontPos--;
while(Relation[FrontPos][FrontBlankCount++]==' ');
if(FrontBlankCount+2==FrontBlank){
break;
}
}
while(BehindPos>=1){
int BehindBlankCount=0;
BehindPos--;
while(Relation[BehindPos][BehindBlankCount++]==' ');
if(BehindBlankCount+2==BehindBlank){
break;
}
}
if(BehindPos==FrontPos){
printf("True\n");
}else{
printf("False\n");
}
}else{
printf("False\n");
}
// X is a descendant of Y
}else if(strstr(Sentence,"descendant")){
if(FrontBlank>BehindBlank){
int BlankCount=FrontBlank;
while(BlankCount!=BehindBlank && FrontPos>=BehindPos){
BlankCount=0;
FrontPos--;
while(Relation[FrontPos][BlankCount++]==' ');
}
if(BlankCount==BehindBlank && FrontPos == BehindPos){
printf("True\n");
}else{
printf("False\n");
}
}else{
printf("False\n");
}
// X is an ancestor of Y
}else if(strstr(Sentence,"ancestor")){
if(FrontBlank<BehindBlank){
int BlankCount=FrontBlank,flag=0;
while(FrontPos<BehindPos){
int BlankTemp=0;
BehindPos--;
while(Relation[BehindPos][BlankTemp++]==' ');
if(BlankCount==BlankTemp){
flag=1;
break;
}
}
if(flag){
printf("True\n");
}else{
printf("False\n");
}
}else{
printf("False\n");
}
}
}
return 0;
}
char *Trim(char a[]){
int BlankCount=0;
while(a[BlankCount++]==' ');
char *Re=(char*)malloc(sizeof(char)*LOCALAUTO);
strcpy(Re,a+BlankCount-1);
return Re;
}
void getName(char Sentence[],char Front[],char Behind[]){
int BlankCount=0;
while(Sentence[BlankCount++]!=' ');
strncpy(Front,Sentence,BlankCount);
Front[BlankCount-1]='\0';
int BlankTimes=0;
while(BlankTimes!=4){
if(Sentence[BlankCount++]==' '){
BlankTimes++;
}
}
strcpy(Behind,Sentence+BlankCount);
}