7-27 家谱处理 (30 分)

人类学研究对于家族很感兴趣,于是研究人员搜集了一些家族的家谱进行研究。实验中,使用计算机处理家谱。为了实现这个目的,研究人员将家谱转换为文本文件。下面为家谱文本文件的实例:

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);
}

猜你喜欢

转载自blog.csdn.net/qq_43209531/article/details/89680051