请用c++代码实现基于三国人物关系数据,构建三国人物关系图。图的顶点为三国人物。边为人物关系(如儿子、义弟、主公)。本题需要实现在图结构上做的各种人物关系查询。人物的属性包括:人名、所属国。 如刘备(刘备,蜀国) 【功能】 1.基于邻接表构建三国人物关系图,并能输出展示邻接表,保存在文件”TRKGraph.txt”中。文件格式如下: 刘备-->张飞--->关羽--->赵云 注意:图的构建,应该先整理图中的顶点数据,即要整理所有三国人物数据作为图顶点。 2.统计人物关系数量最多的前10个三国人物及其所属国。 3.输入2个人物,查找2个人物之间所有关系。基于图的深度遍历,展示关系路径。并能说明最短路径是哪条。答辩时候展示:有关系的人物。无关系的人物。 4.智能问答。输入荀彧的主公的儿子是谁?能输出关系路径,并给出答案。
时间: 2024-03-18 17:43:14 浏览: 154
以下是基于邻接表实现的c++代码,实现了上述所有功能:
```c++
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <queue>
#include <stack>
using namespace std;
// 定义人物结构体
struct Person {
string name;
string country;
};
// 定义边结构体
struct Edge {
string relation;
Person* person;
};
// 定义图类
class Graph {
private:
// 存储顶点和边的邻接表
unordered_map<string, vector<Edge>> adj_list;
// 存储所有顶点的name和country
unordered_map<string, string> vertex_info;
public:
// 添加顶点
void add_vertex(Person* person) {
adj_list[person->name] = vector<Edge>();
vertex_info[person->name] = person->country;
}
// 添加边
void add_edge(string from, string to, string relation) {
Person* p = new Person{ to, vertex_info[to] };
Edge e = { relation, p };
adj_list[from].push_back(e);
}
// 输出邻接表
void print_graph() {
ofstream out("TRKGraph.txt");
for (auto it = adj_list.begin(); it != adj_list.end(); it++) {
out << it->first;
for (auto edge : it->second) {
out << "--" << edge.relation << "-->" << edge.person->name;
}
out << endl;
}
out.close();
}
// 统计人物关系数量最多的前10个三国人物及其所属国
void top_10_relations() {
unordered_map<string, int> relation_count;
for (auto it = adj_list.begin(); it != adj_list.end(); it++) {
relation_count[it->first] = 0;
for (auto edge : it->second) {
relation_count[edge.person->name]++;
}
}
vector<pair<string, int>> count_vec;
for (auto it = relation_count.begin(); it != relation_count.end(); it++) {
count_vec.push_back(*it);
}
sort(count_vec.begin(), count_vec.end(), [](pair<string, int>& a, pair<string, int>& b) {
return a.second > b.second;
});
cout << "人物关系数量最多的前10个三国人物及其所属国:" << endl;
for (int i = 0; i < min((int)count_vec.size(), 10); i++) {
cout << count_vec[i].first << "(" << vertex_info[count_vec[i].first] << "):" << count_vec[i].second << endl;
}
}
// 搜索从from到to的路径,使用深度优先搜索
void dfs_path(string from, string to, vector<string>& visited, vector<string>& path, vector<vector<string>>& paths) {
visited.push_back(from);
path.push_back(from);
if (from == to) {
paths.push_back(path);
visited.pop_back();
path.pop_back();
return;
}
for (auto edge : adj_list[from]) {
string next_name = edge.person->name;
if (find(visited.begin(), visited.end(), next_name) == visited.end()) {
dfs_path(next_name, to, visited, path, paths);
}
}
visited.pop_back();
path.pop_back();
}
// 查找2个人物之间所有关系,展示关系路径,并说明最短路径
void find_path(string from, string to) {
vector<string> visited;
vector<string> path;
vector<vector<string>> paths;
dfs_path(from, to, visited, path, paths);
if (paths.empty()) {
cout << "这两个人没有关系" << endl;
}
else {
cout << "这两个人之间所有关系路径:" << endl;
for (auto p : paths) {
for (int i = 0; i < p.size() - 1; i++) {
cout << p[i] << "--" << get_relation(p[i], p[i + 1]) << "-->";
}
cout << p.back() << endl;
}
cout << "最短路径:" << endl;
vector<string> shortest_path = get_shortest_path(paths);
for (int i = 0; i < shortest_path.size() - 1; i++) {
cout << shortest_path[i] << "--" << get_relation(shortest_path[i], shortest_path[i + 1]) << "-->";
}
cout << shortest_path.back() << endl;
}
}
// 智能问答
void intelligent_qa(string name) {
string master = get_master(name);
if (master == "") {
cout << "找不到这个人" << endl;
return;
}
string son = get_son(master);
if (son == "") {
cout << master << "没有儿子" << endl;
}
else {
vector<string> visited;
vector<string> path;
vector<vector<string>> paths;
dfs_path(name, son, visited, path, paths);
cout << name << "的主公的儿子是" << son << endl;
if (paths.empty()) {
cout << "他们之间没有关系" << endl;
}
else {
cout << "他们之间的关系路径:" << endl;
for (auto p : paths) {
for (int i = 0; i < p.size() - 1; i++) {
cout << p[i] << "--" << get_relation(p[i], p[i + 1]) << "-->";
}
cout << p.back() << endl;
}
}
}
}
private:
// 获取某个人物的主公
string get_master(string name) {
for (auto it = adj_list.begin(); it != adj_list.end(); it++) {
for (auto edge : it->second) {
if (edge.person->name == name && edge.relation == "主公") {
return it->first;
}
}
}
return "";
}
// 获取某个人物的儿子
string get_son(string name) {
for (auto edge : adj_list[name]) {
if (edge.relation == "儿子") {
return edge.person->name;
}
}
return "";
}
// 获取两个人物之间的关系
string get_relation(string from, string to) {
for (auto edge : adj_list[from]) {
if (edge.person->name == to) {
return edge.relation;
}
}
return "";
}
// 获取最短路径
vector<string> get_shortest_path(vector<vector<string>>& paths) {
int shortest_len = INT_MAX;
vector<string> shortest_path;
for (auto p : paths) {
if (p.size() < shortest_len) {
shortest_len = p.size();
shortest_path = p;
}
}
return shortest_path;
}
};
int main() {
// 构建三国人物关系图
Graph graph;
// 添加顶点
vector<Person*> persons = {
new Person{ "刘备", "蜀国" },
new Person{ "关羽", "蜀国" },
new Person{ "张飞", "蜀国" },
new Person{ "诸葛亮", "蜀国" },
new Person{ "张松", "汉中" },
new Person{ "程昱", "曹魏" },
new Person{ "曹操", "曹魏" },
new Person{ "曹丕", "曹魏" },
new Person{ "曹植", "曹魏" },
new Person{ "夏侯惇", "曹魏" },
new Person{ "夏侯渊", "曹魏" },
new Person{ "典韦", "曹魏" },
new Person{ "张辽", "曹魏" },
new Person{ "
阅读全文