定义一种简单的知识图谱:
概念:包括父概念及其子概念,通过subClassOf关系联系,父子概念可以有多个层级;
实例:仅和概念之间通过instanceOf关系关联;
关系:通过字符串表示。“student subClassOf person”表示student是person的子概念;“apple instanceOf fruit”表示apple是概念fruit的实例。
编写一个方法。根据概念返回其所有实例(包括子概念的实例;如果没有实例就返回“empty”。
给定的图谱满足:有向图不存在环路;所有点和关系的定义对大小写敏感。
输入第一行为n,取值范围[1,10000],表示图谱中关系的数量。
第2行到第n+1行,每一行表示一组关系。
第n+2行,表示待查找的元节点。
思路:通过哈希表实现概念的快速查找;哈希表的值记录下属的子概念和实例。
#include<iostream>
#include<string>
#include<unordered_map>
#include<vector>
using namespace std;
struct recordNode
{
vector<string> son;
vector<string> instance;
};
void findandpr(unordered_map<string, recordNode*> &hash,vector<string>& resr, string refind) {
if (hash.count(refind)) {
for (auto x : hash[refind]->instance) {
resr.push_back(x);
}
for (auto y : hash[refind]->son)
findandpr(hash, resr, y);
}
return;
}
int main() {
int num;
cin >> num;
cin.ignore();
unordered_map<string, recordNode *> hash;
while (num--) {
string inputs;
getline(cin, inputs);
vector<string> res;
while (!inputs.empty()) {
int start = 0;
if (inputs.find(' ',start) == inputs.npos) {
res.push_back(inputs);
break;
}
int pos = inputs.find(' ', start);
string temp = inputs.substr(start, pos);
inputs.erase(start, pos + 1);
res.push_back(temp);
}
if (res[1] == "subClassOf") {
if (!hash.count(res[2])) {
recordNode* re = new recordNode;
re->son.push_back(res[0]);
hash.insert(pair<string, recordNode*>(res[2], re));
}
else {
hash[res[2]]->son.push_back(res[0]);
}
}
else {
if (!hash.count(res[2])) {
recordNode* re = new recordNode;
re->instance.push_back(res[0]);
hash.insert(pair<string, recordNode*>(res[2], re));
}
else {
hash[res[2]]->instance.push_back(res[0]);
}
}
}
string refind;
cin >> refind;
vector<string> resr;
findandpr(hash, resr, refind);
for (string x : resr) {
cout << x << " ";
}
cout << endl;
return 0;
}