C语言 家谱问题

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

家谱文本文件中,每一行包含一个人的名字。第一行中的名字是这个家族最早的祖先。家谱仅包含最早祖先的后代,而他们的丈夫或妻子不出现在家谱中。每个人的子女比父母多缩进2个空格。以上述家谱文本文件为例,John这个家族最早的祖先,他有两个子女Robert和Nancy,Robert有两个子女Frank和Andrew,Nancy只有一个子女David。

在实验中,研究人员还收集了家庭文件,并提取了家谱中有关两个人关系的陈述语句。下面为家谱中关系的陈述语句实例:

John is the parent of Robert

David is a descendant of Robert

Robert is a sibling of Nancy

研究人员需要判断每个陈述语句是真还是假,请编写程序帮助研究人员判断。为简化程序,我们约定测试数据中出现的每个人,其子女不超过2个。

输入
输入首先给出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

请发至我邮箱 pgbxs31@163.com
最新回答
女中豪杰

2024-11-24 07:58:45

#include<stdio.h>
#include<string.h>
char w[5][20]={{"child"},{"parent"},{"sibling"},{"descendant"},{"ancestor"}};
    int kong(char a[]) {
    int n=0,i;
    for(i=0;a[i]!='\0';i++) {
    if(a[i]==' ')
    n++;
    else
    break;
    }
    return n;
}

char fam[200][20];
int num[200]={0};

int search(char a[],int n) {
    int i=1;
    while(1) {
    if(!strcmp(a,fam[i]))
    return i;
    i++;
    }
    return 0;
}

int search1(int n,int x) {
    int i=1;
    while(i<x) {
    if(num[i]==n)
    return i;
    i++;
    }
    return 0;
}

char name[1000],word[1000],n1[100],n2[100],d[100];
int main() {
    int n,m,i,j,a,b,t,x,k,h;
    while(scanf("%d%d",&n,&m)!=EOF) {
        memset(fam,'\0',sizeof(fam));
        memset(num,'\0',sizeof(num));
        scanf("%s",fam[1]);
        getchar();
        a=b=2;
        t=1;
        num[1]=1;
    for(i=2;i<=n;i++) {
        memset(name,'\0',sizeof(name));
        gets(name);
        b=kong(name);
        if(b>a) {
            if(fam[search1(t*2+1,i)][0]!='\0')
                t=t*2+1;
            else 
                t=t*2;
        }
        else { if(b<a) {
            h=(a-b)/2;
            while(h>=1) {
                t=t/2;
                h--;
            }
        }}
    if(fam[search1(t*2,i)][0]!='\0')
    x=t*2+1;
    else x=t*2;
    num[i]=x;
    for(j=b;name[j]!='\0';j++)
    fam[i][j-b]=name[j];
    a=b;
    }
    for(i=0;i<m;i++) {
    gets(word);
    k=0;h=0;
    memset(n1,'\0',sizeof(n1));
    memset(n2,'\0',sizeof(n2));
    memset(d,'\0',sizeof(d));
    for(j=0;word[j]!='\0';j++) {
    if(word[j]==' ') {
    k++;
    h=0;
    continue;
    }
    if(k==0)
    n1[j]=word[j];
    if(k==5) {
    n2[h]=word[j];
    h++;
    }
    if(k==3) {
    d[h]=word[j];
    h++;
    }
    }
    if(!strcmp(d,w[0])) {
    a=search(n1,n);a=num[a];
    b=search(n2,n);b=num[b];
    if(a==b*2||a==(b*2+1))
    printf("True\n");
    else printf("False\n");
    continue;
    }
    if(!strcmp(d,w[1])) {
    a=search(n1,n);a=num[a];
    b=search(n2,n);b=num[b];
    if(b==a*2||b==(a*2+1))
    printf("True\n");
    else printf("False\n");
    continue;
    }
    if(!strcmp(d,w[2])) {
    a=search(n1,n);a=num[a];
    b=search(n2,n);b=num[b];
    if((a==b+1&&a==b/2*2+1)||(a==b-1&&b==a/2*2+1))
    printf("True\n");
    else printf("False\n");
    continue;
    }
    if(!strcmp(d,w[3])) {
    a=search(n1,n);a=num[a];
    b=search(n2,n);b=num[b];
    while(a>0) {
    a=a/2;
    if(a==b) {
    printf("True\n");
    break;
    }
    if(a==0)
    printf("False\n");
    }
    continue;
    }
    if(!strcmp(d,w[4])) {
    a=search(n1,n);a=num[a];
    b=search(n2,n);b=num[b];
    while(b>0) {
    b=b/2;
    if(a==b) {
    printf("True\n");
    break;
    }
    if(b==0)
    printf("False\n");
    }
    continue;
    }
    }
    }
    return 0;
}

听说回答的够长能够自动采纳

追问
这又不是你自己写的
追答
你想自己写吗
媤惗ら

2024-11-24 07:58:28

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define R_CHILD "child"
#define R_ANCESTOR "ancestor"
#define R_SIBLING "sibling"
#define R_PARENT "parent"
#define R_DESC "descendant"

typedef unsigned int  uint32;
typedef struct _member
{
//当前代数编号,首代为1(其实等于缩进格数/2+1 )
uint32 cur_generation;
uint32 cur_no; //自己编号
uint32 parent_no; //父编号
char name[32];
}Member;

typedef enum bool
{
false = 0,
true = 1
}BOOL;

#define LEN_NAME 64
#define LEN_SENTENCE 128
typedef struct  stru_sentence
{
char sentence[LEN_SENTENCE];
char x[LEN_NAME];
char y[LEN_NAME];
char relation[LEN_NAME];
}StruSentence;

int parse_sentence(StruSentence *psentence);
BOOL is_true_sentence(const Member * pmember, uint32 nmember, StruSentence *psentence);


void init_member(Member **ppmember, uint32 nmember)
{
uint32 len = sizeof(Member)*nmember;
*ppmember = (Member*)malloc(len);
memset(*ppmember, 0, len);
}

void init_sentence(StruSentence **ppsentence, uint32 nsentence)
{
uint32 len = sizeof(StruSentence)*nsentence;
*ppsentence = (StruSentence*)malloc(len);
memset(*ppsentence, 0, len);
}

int read_all(Member **ppmember, uint32 *pnmember, StruSentence **ppsentence, uint32 *pnsentence)
{
uint32 ind = 0;
FILE *pfile = fopen("family.txt", "r");
if (pfile == NULL)
return -1;
#define MAX_LINE 256
#define MAX_LEN_NUMBER 8
char buf[MAX_LINE] = {0};

//读取数字
char cmember[MAX_LEN_NUMBER] = {0};
char csentence[MAX_LEN_NUMBER] = {0};
if (fgets(buf, MAX_LINE, pfile) != NULL)
{

uint32 i = 0;
for (; i < strlen(buf); ++i)
{
if (buf[i] != ' ')
{
cmember[i] = buf[i];
}
else
break;
}
*pnmember = atoi(cmember);
uint32 temp = 0;
for (; i < strlen(buf); ++i)
{
if (buf[i] != ' ')
{
csentence[temp++] = buf[i];
}
}
*pnsentence = atoi(csentence);
 
}

Member *pmember = NULL;
init_member(&pmember, *pnmember);
*ppmember = pmember;

StruSentence *psentence = NULL;
init_sentence(&psentence, *pnsentence);
*ppsentence = psentence;

//读取人物
while (ind < *pnmember && fgets(buf, MAX_LINE, pfile) != NULL)
{
uint32 nspace = 0;
uint32 i = 0;
for (; i < strlen(buf); ++i)
{
if (buf[i] != 13 && buf[i] != 10)
{
if (buf[i] == ' ')
++nspace;
else
pmember[ind].name[i-nspace] = buf[i];
}
else
break;
}
pmember[ind].cur_generation = nspace/2 + 1;
pmember[ind].cur_no = ind;
++ind;
}

//读取句子
ind = 0;
while (ind < *pnsentence && fgets(psentence[ind].sentence, MAX_LINE, pfile) != NULL)
{
++ind;
}

fclose(pfile);

return 0;
}

void parse_relation(Member *pmember, uint32 nmember)
{
pmember[0].parent_no = 0;
uint32 i = nmember - 1;
for (; i > 0; --i)
{
uint32 j = i - 1;
for (; j >= 0; --j)
{
if (pmember[i].cur_generation - 1 == pmember[j].cur_generation)
{
pmember[i].parent_no = pmember[j].cur_no;
break;
}
}
}
for (i = 0; i < nmember; ++i)
printf("name=[%s], generation[%d], cur_no[%d], p[%d]\n", 
pmember[i].name, pmember[i].cur_generation, pmember[i].cur_no, pmember[i].parent_no);
}

uint32 get_no_by_name(const Member *pmember, uint32 nmember, const char* pname)
{
uint32 i = 0;
for (i = 0; i < nmember; ++i) 
{
if (strcmp(pmember[i].name, pname) == 0)
return pmember[i].cur_no;
}

return 0;
}


BOOL is_true_sentence(const Member * pmember, uint32 nmember, StruSentence *psentence)
{
uint32 xid = get_no_by_name(pmember, nmember, psentence->x);
uint32 yid = get_no_by_name(pmember, nmember, psentence->y);

if (strstr(psentence->relation, R_CHILD) != NULL)
{
if (pmember[xid].parent_no ==  pmember[yid].cur_no)
return true;
}
else if (strstr(psentence->relation, R_ANCESTOR) != NULL)
{
if (pmember[xid].cur_generation == 0)
return true;

uint32 temp = pmember[yid].parent_no;
while (temp > 0)
{
if (temp == pmember[xid].cur_no)
return true;

temp = pmember[temp].parent_no;
}
}
else if (strstr(psentence->relation, R_DESC) != NULL)
{
if (pmember[yid].cur_generation == 0)
return true;

uint32 temp = pmember[xid].parent_no;
while (temp > 0)
{
if (temp == pmember[yid].cur_no)
return true;

temp = pmember[temp].parent_no;
}
}
else if (strstr(psentence->relation, R_PARENT) != NULL)
{
if (pmember[yid].parent_no ==  pmember[xid].cur_no)
return true;
}
else if (strstr(psentence->relation, R_SIBLING) != NULL)
{
if (pmember[xid].parent_no == pmember[yid].parent_no)
return true;
}

return false;
}

int parse_sentence(StruSentence *psentence)
{
//assert(psentence->sentence[0]  != '\0');
uint32 i = 0;

for (; i < strlen(psentence->sentence); ++i)
{
if (psentence->sentence[i] != ' ')
psentence->x[i] = psentence->sentence[i];
else 
break;
}
for (; i < strlen(psentence->sentence); ++i)
{
if (psentence->sentence[i-2] == 'o' 
&& psentence->sentence[i-1] == 'f' 
&& psentence->sentence[i] == ' ')
break;
}
++i;
uint32 ntemp = 0;
for (; i < strlen(psentence->sentence); ++i)
{
if (psentence->sentence[i] != 10 && psentence->sentence[i] != 13)
{
psentence->y[ntemp++] = psentence->sentence[i];
}
else
break;
}

if (strstr(psentence->sentence, R_CHILD) != NULL)
{
strcpy(psentence->relation, R_CHILD);
}
else if (strstr(psentence->sentence, R_ANCESTOR) != NULL)
{
strcpy(psentence->relation, R_ANCESTOR);
}
else if (strstr(psentence->sentence, R_DESC) != NULL)
{
strcpy(psentence->relation, R_DESC);
}
else if (strstr(psentence->sentence, R_PARENT) != NULL)
{
strcpy(psentence->relation, R_PARENT);
}
else if (strstr(psentence->sentence, R_SIBLING) != NULL)
{
strcpy(psentence->relation, R_SIBLING);
}

//printf("x[%s],y[%s], relation[%s]\n", psentence->x, psentence->y, psentence->relation);

return 0;
}

void test_family(int argc, char *argv[])
{
Member *pmember = NULL;
uint32 nmember = 0;
uint32 nsentence = 0;

StruSentence *psentence = NULL;
if (read_all(&pmember, &nmember, &psentence, &nsentence) == -1)
return;

parse_relation(pmember, nmember);

////测试---begin
uint32 ind = 0;

for (; ind < nsentence; ++ind)
{
printf("[%s]\n", psentence[ind].sentence);
parse_sentence(&psentence[ind]);
BOOL ret = is_true_sentence(pmember, nmember, &psentence[ind]);
if (ret)
printf("is true..\n");
else
printf("is false..\n");
}
////测试---end

}

int main(int argc, char *argv[])
{
test_family(argc, argv);
return 0;
}


测试时没有使用输入方式,采用读取文件的方式。工程发你邮箱,若有问题,请继续。望采纳

候补的爱人

2024-11-24 07:56:48

帮做20微信红包
追问
微信号?