1. 程式人生 > >資料結構與演算法題目集7-27——家譜處理

資料結構與演算法題目集7-27——家譜處理

我的資料結構與演算法題目集程式碼倉: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++解題報告: