前言:仅供参考学习
题目:查找知识图谱中的实例知识
题目描述:
知识图谱的实例(200分)
知识图谱是一种结构化的语义网络,用于描述物理世界中的概念及其实例的相关关系。
可以把知识图谱看成是以种有向图,图中的点是概念或实例,图中的边是概念及其实例的相关
光系。
现定义一种简单的知识图谱:
概念:包括父概念及其子概念,通过subClassOf关联关系,父子概念可以游多个层级
实例:仅和概念之间通过instanceOf关系关联;
关系:以三元组的形式表示,三元组是一个以空格为成员间分隔符的字符串。
例如:“student subClassOf fruit”表示student是person的子概念;
“apple instanceOf fruit”表示apple是概念fruit的实例
给定一个资是图谱,请编写一个方法,可以根据一个概念查找其所有的实例
如果一个概念拥有子概念,那么返回的结构需要包含其所有子概念的实例;
如果输入的概念没有实例,则返回字符串“empty”(说明:输出字符串文本不需要包含
引号)
给定的图谱满足一下限制:
1.有向图中不存在环路;
2.所有点和关系的定义对大小写敏感;
输入:
输入第一行,表示图谱中关系的数量n,取值范围【1,10000】;
从第二行到第n+1行,表示图谱中的关系,每一行是一个关系三元组;
第n+2行,表示待查的元节点,是关系三元组中存在的点;
每行字符的长度不超过100
输出:
按字典序升序排列的字符串数组,其内容是概念及其子概念的所有实例。
样例一:
输入:
3
student subClassOf person
Tom instanceOf student
Marry instanceOf person
person
输出:
Marry Tom
解释:student是person的子概念,Tom是student的实例,Marry是person的实例,Marry的字典序小于Tom,所以Marry Tom
样例二:
1
student subClassOf person
person
输出:
empty
解释没有实例。
参考代码:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
struct Node {
string key;
vector<string> *lg = nullptr; //存放这个概念包含实例;
vector<Node>* childnode = nullptr; //存放子概念
Node(string k) :key(k)
{
lg = new vector<string>();
childnode = new vector<Node>();
}
bool operator <(const Node& a)const
{
return key < a.key;
}
};
struct cmp {
bool operator ()(string &a,string &b)
{
return a > b;
}
};
int main()
{
int n;
cin >> n;
map<string, Node> graph; //图
string line;
vector<vector<string>> vec;
for (int i = 0;i<=n;i++) //建立一张图
{
getline(cin,line);
stringstream ss(line);
string temp;
vector<string> vec_temp;
if (i == 0)continue;
while (getline(ss,temp,' '))
{
vec_temp.emplace_back(temp);
}
vec.emplace_back(vec_temp);
if (graph.find(vec_temp[2]) == graph.end()) //如果这个概念没有的话,
{
graph.emplace(vec_temp[2],Node(vec_temp[2])); //为图中新建一个点
}
if (vec_temp[1] == "subClassOf") //概念关联
{
if (graph.find(vec_temp[0]) == graph.end())
{
graph.emplace(vec_temp[0],Node(vec_temp[0]));
}
Node sub = graph.find(vec_temp[0])->second;
graph.find(vec_temp[2])->second.childnode->emplace_back(sub);
}
else { //实例关联
string instance = vec_temp[0];
graph.find(vec_temp[2])->second.lg->emplace_back(instance);
}
}
//bfs
priority_queue<string, vector<string>, cmp> b_heal; //大根堆
string target;
cin >> target;
queue<Node> myqueue;
myqueue.push(graph.find(target)->second);
while (!myqueue.empty())
{
int n = myqueue.size();
for (int i = 0;i<n;i++)
{
Node tp = myqueue.front();
myqueue.pop();
for (auto k:*tp.lg) //存进实例
{
b_heal.emplace(k);
}
for (auto j : *tp.childnode)
{
myqueue.push(j);
}
}
}
if (b_heal.empty())
{
cout << "empty" << endl;
return 0;
}
while (!b_heal.empty())
{
cout << b_heal.top() << ' ';
b_heal.pop();
}
//最后应该释放node中申请的内存
return 0;
}
小结:图这个数据结构建图比较麻烦。这道题是一道bfs的题目。代码注释得比较清晰了,看下代码就知道思路了。