我的数据结构与算法题目集代码仓:https://github.com/617076674/Data-structure-and-algorithm-topic-set
原题链接:https://pintia.cn/problem-sets/15/problems/842
题目描述:
知识点:字符串处理
思路:对5种关系写5个判断函数
在读取数据过程中,需要保存3个信息,一个map<string, int>型变量stringToInt,代表名字对应的编号,编号从0开始;一个char型二维数组intToString[100][11],代表编号对应的名字;一个int型数组spaces[100],代表每行对应的空格数,行号即改行名字对应的编号,显然也是从0开始。
为了读取每行第一个字符前的空格数量,我选择了getchar()函数一个个字符地读取,对空格数量进行计数,读取每一行就更新上述三个变量。注意,二维char型数组的赋值需要用到<cstring>头文件中的strcpy()函数。
对于待判断语句的读取,考虑到每个语句都由6个字符串组成,由5个空格分隔,我用6个char型数组变量str1 ~ str6,分别保存这6个字符串的信息。其中str1和str6分别代表名字,str4代表待判断的关系。将str1和str6分别转换成行号line1和line2,再根据str4的关系选择判断函数,判断该语句是否正确。判断函数有以下5个:
(1)x是否是y的孩子
a:如果x前面的空格数减去2不等于y前面的空格数,显然x不是y的孩子。
b:如果x < y,显然x不是y的孩子。
c:如果在行号(y, x]之间,存在某一行,其前面的空格数小于x前面的空格数,x不是y的孩子。这种情况类似于样例中的"David"和"Robert"的关系。
d:除去以上3种情况外,我们可以判断x是y的孩子。
(2)x是否是y的父母
a:如果x前面的空格数加上2不等于y前面的空格数,显然x不是y的父母。
b:如果x > y,显然x不是y的父母。
c:如果在行号(x, y]之间,存在某一行,其前面的空格数小于y前面的空格数,x不是y的父母。这种情况类似于样例中的"David"和"Robert"的关系。
d:除去以上3种情况外,我们可以判断x是y的父母。
(3)x是否是y的兄弟姐妹
a:如果x和y前面的空格数不相等,x不是y的兄弟姐妹。
b:假设x < y,在(x, y)范围内,如果存在某一行,其前面的空格数小于y前面的空格数,x不是y的兄弟姐妹。这种情况类似于样例中"David"和"Andrew"的关系。
c:除去以上2种情况外,我们可以判断x是y的兄弟姐妹。
(4)x是否是y的后代
a:如果x前面的空格数小于y前面的空格数,显然x不是y的后代。
b:如果x < y,显然x不是y的后代。
c:从y + 1行开始,直到某一行,该行前面的空格数和y行前面的空格数相等,如果在这个过程中发现了编号x,x是y的后代;否则,x不是y的后代。
(5)x是否是y的祖先
a:如果x前面的空格数大于y前面的空格数,显然x不是y的祖先。
b:如果x > y,显然x不是y的祖先。
c:从x + 1行开始,直到某一行,该行前面的空格数和x行前面的空格数相等,如果在这个过程中发现了编号y,x是y的祖先;否则,x不是y的祖先。
时间复杂度和查询语句的两个名字对应的编号间距有关。空间复杂度是O(100 * 11)。
C++代码:
#include<iostream>
#include<map>
#include<string>
#include<cstring>
using namespace std;
int N, M;
map<string, int> stringToInt; //名字编号,从0开始编号
char intToString[100][11]; //编号对应的名字,和stringToInt编号一致,也是从0开始编号
int spaces[100]; //每行对应的空格数,从0行开始计数
bool x_child_y(int x, int y);
bool x_parent_y(int x, int y);
bool x_sibling_y(int x, int y);
bool x_descendant_y(int x, int y);
bool x_ancestor_y(int x, int y);
int main() {
scanf("%d %d", &N, &M);
getchar();
for(int i = 0; i < N; i++) {
char c;
int space = 0;
while((c = getchar()) == ' ') {
space++;
}
char name[11];
name[0] = c;
int index = 1;
while((c = getchar()) != '\n') {
name[index++] = c;
}
name[index] = '\0';
stringToInt[name] = i;
strcpy(intToString[i], name);
spaces[i] = space;
}
for(int i = 0; i < M; i++){
char str1[11], str2[3], str3[4], str4[11], str5[3], str6[11];
scanf("%s %s %s %s %s %s", str1, str2, str3, str4, str5, str6);
int line1 = stringToInt[str1];
int line2 = stringToInt[str6];
if(strcmp(str4, "child") == 0){
if(x_child_y(line1, line2)){
printf("True\n");
}else{
printf("False\n");
}
}else if(strcmp(str4, "parent") == 0){
if(x_parent_y(line1, line2)){
printf("True\n");
}else{
printf("False\n");
}
}else if(strcmp(str4, "sibling") == 0){
if(x_sibling_y(line1, line2)){
printf("True\n");
}else{
printf("False\n");
}
}else if(strcmp(str4, "descendant") == 0){
if(x_descendant_y(line1, line2)){
printf("True\n");
}else{
printf("False\n");
}
}else if(strcmp(str4, "ancestor") == 0){
if(x_ancestor_y(line1, line2)){
printf("True\n");
}else{
printf("False\n");
}
}
}
return 0;
}
bool x_child_y(int x, int y){
if(spaces[x] - 2 != spaces[y]){
return false;
}
if(x < y){
return false;
}
for(int i = y + 1; i <= x; i++){
if(spaces[i] < spaces[x]){
return false;
}
}
return true;
}
bool x_parent_y(int x, int y){
if(spaces[x] + 2 != spaces[y]){
return false;
}
if(x > y){
return false;
}
for(int i = x + 1; i <= y; i++){
if(spaces[i] < spaces[y]){
return false;
}
}
return true;
}
bool x_sibling_y(int x, int y){
if(spaces[x] != spaces[y]){
return false;
}
if(x > y){
swap(x, y);
}
for(int i = x + 1; i <= y; i++){
if(spaces[i] < spaces[y]){
return false;
}
}
return true;
}
bool x_descendant_y(int x, int y){
if(spaces[x] < spaces[y]){
return false;
}
if(x < y){
return false;
}
int index = y + 1;
while(true){
if(spaces[index] == spaces[y]){
return false;
}
if(index == x){
return true;
}
index++;
}
}
bool x_ancestor_y(int x, int y){
if(spaces[x] > spaces[y]){
return false;
}
if(x > y){
return false;
}
int index = x + 1;
while(true){
if(spaces[index] == spaces[x]){
return false;
}
if(index == y){
return true;
}
index++;
}
}
C++解题报告: