家系図処理(30点)(地図マッピング)

人類学的研究は家族に非常に興味があるので、研究者は研究のためにいくつかの家族の系図を集めました。実験では、コンピューターを使用して家系図を処理しました。この目標を達成するために、研究者たちは家系図をテキストファイルに変換しました。以下は、系図テキストファイルの例です。

ジョン
ロバート
フランク
アンドリュー
ナンシー
ダビデの
家系図テキストファイルでは、各行に人の名前が含まれています。最初の行の名前は、この家族の最初の祖先です。系図には、最も古い祖先の子孫のみが含まれ、その夫または妻は系図に表示されません。すべての子供は、親より2スペース多くインデントされています。上記の系図テキストファイルを例にとると、ジョンの家系の最初の祖先にはロバートとナンシーの2人の子供がいて、ロバートにはフランクとアンドリューの2人の子供がいて、ナンシーにはデビッドの子供が1人しかいません。

実験では、研究者は家族の文書を収集し、家系図の2人の関係についてのステートメントを抽出しました。以下は、家系図の関係のステートメント文の例です。

ジョンはロバートの親ですロバート
はナンシーの兄弟です
デビッドはロバートの子孫です
研究者は各ステートメントが正しいか間違っているかを判断する必要があります。研究者が判断するのに役立つプログラムを書いてください。
入力形式:
入力は最初に2つの正の整数N(2≤N≤100)とM(≤100)を与えます。ここで、Nは家系図の名前の数、Mは家系図のステートメント文の数です。入力の各行は70文字を超えません。

名前の文字列は、10文字以下の英字で構成されます。系図の最初の行に示されている名前の前にインデントスペースはありません。家系図の他の名前は、少なくとも2スペースインデントする必要があります。つまり、家系図の最初の祖先(最初の行に示されている名前)の子孫であり、家系図の名前がkスペースインデントされている場合名前の前の次の行の名前は、最大でk +2スペースをインデントします。

同じ名前が系図に2回表示されることはなく、系図に表示されない名前はステートメントに表示されません。各ステートメントの形式は次のとおりです。ここで、XとYは家系図で異なる名前です。

XはYの子です
XはYの親です
XはYの兄弟です
XはYの子孫です
XはYの祖先です
出力形式:
テストケースの各ステートメントについて、ステートメントが次の場合、1行でTrueを出力します。 true、またはステートメントがfalseの場合はFalse。

質問のアイデア:

1。各人の父親を1つずつマッピングし、マップマッピングを使用し、マップマップを適切に作成するための補助配列を追加する方法。
2.与えられた宣言文のキーワードを抽出し、他の人との関係を特定します。

#include<iostream>
#include<map>
#include<algorithm>
#include<string>
using namespace std;

void BuildFamily();
int n, m;
map<string, string> parent;
string ar[1000];
int main()
{
    
    
	bool table[1000] = {
    
     false }, k = 0;
	BuildFamily();
	int t = m;
	while (m--)
	{
    
    
		string a, b, c, e;
		cin >> a >> e >> e >> b >> e >> c;

		switch (b[0])
		{
    
    
		case'c':
			swap(a, c);		//放到下一步处理,所以没有加break;
		case'p':
			if (parent[c] == a)
				cout << "True\n";
			else
				cout << "False\n";
			break;
		case's':
			if (parent[a] == parent[c])
				cout << "True\n";
			else
				cout << "False\n";
			break;
		case'd':
			swap(a, c);			//放到下一步处理
		case'a':
			if (a == "root")
			{
    
    
				cout << "True\n";
				break;
			}
			else
			{
    
    
				while (parent[c] != a && parent[c] != "root")c = parent[c];
				if (parent[c] == a)				//要么parent[c]==a,要么parent[c]==root了
					cout << "True\n";
				else
					cout << "False\n";
				break;
			}
		}
	}
	return 0;
}
void BuildFamily()
{
    
    
	cin >> n >> m;
	getchar();			//吸收回车,确保下一步的getline正常运行
	for (int i = 0; i < n; i++)
	{
    
    
		string st;
		getline(cin, st);
		int cnt = count(st.begin(), st.end(), ' ');

		if (cnt == 0)	//把资历最老的祖先先定位好
		{
    
    
			parent[st] = "root";		
			ar[1] = st;
		}
		else
		{
    
    
			st = st.substr(cnt);	//如果有空格,跳过空格读取有效字符串
			parent[st] = ar[cnt / 2];	//通过空格的个数把等级划分
			ar[cnt / 2 + 1] = st;		//空格多的放在下一个等级
		}								//再草稿纸上画画这两个下标
	}
}

おすすめ

転載: blog.csdn.net/xdg15294969271/article/details/113995289