请用c++代码实现基于三国人物关系数据,构建三国人物关系图。图的顶点为三国人物。边为人物关系(如儿子、义弟、主公)。本题需要实现在图结构上做的各种人物关系查询。人物的属性包括:人名、所属国。 如刘备(刘备,蜀国) 【功能】 1.基于邻接表构建三国人物关系图,并能输出展示邻接表,保存在文件”TRKGraph.txt”中。文件格式如下: 刘备-->张飞--->关羽--->赵云 注意:图的构建,应该先整理图中的顶点数据,即要整理所有三国人物数据作为图顶点。 2.统计人物关系数量最多的前10个三国人物及其所属国。 3.输入2个人物,查找2个人物之间所有关系。基于图的深度遍历,展示关系路径。并能说明最短路径是哪条。答辩时候展示:有关系的人物。无关系的人物。 4.智能问答。输入荀彧的主公的儿子是谁?能输出关系路径,并给出答案。

时间: 2024-03-18 12:43:14 浏览: 15
以下是基于邻接表实现的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{ "

相关推荐

最新推荐

recommend-type

C++实现视频流转换为图片方式

今天小编就为大家分享一篇C++实现视频流转换为图片方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
recommend-type

C++实现图形界面时钟表盘代码

主要介绍了C++实现图形界面时钟表盘代码,涉及坐标函数的应用及图形界面程序设计,需要的朋友可以参考下
recommend-type

基于QT C++实现的数据结构软件设计报告

哈工大(威海)计算机科学与技术学院 软件设计程序II的实验报告,基于QT,C++实现的简单饮食健康助手小程序,具有一定的数据结构知识的构建。原作者,可私聊源码。
recommend-type

约瑟夫环问题用C++代码实现

从编号为1的人开始报数,数到k的那个人出列;他的下一个人又从1开始报数,数到k的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。 要求:(1)定义递归函数int jos(int n, int k); n表示总人数, k表示...
recommend-type

画太极图的C++代码实现

和课堂上绘制正弦曲线相比 如果用一笔一笔循环的方式画圆将会很复杂 因此我就参考网上的 用Pie函数和Ellipse函数画弧和圆 画图用了CBrush画刷和CPen画笔 "&gt;绘制太极图的原理简单来说就是画两个半圆一黑一白 拼成一...
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

用前端写一个树形控件读取指定目录的文件夹结构

抱歉,作为AI语言模型,我无法提供完整的前端代码。但是,我可以给您一些指导和建议: 1. 使用递归函数来读取指定目录下的所有子文件夹和文件。 2. 在HTML中使用ul和li标签来构建树形结构。 3. 使用CSS样式来美化树形控件。 4. 使用JavaScript来实现树形控件的交互功能(如展开/收起节点)。 5. 使用Ajax或fetch等技术来异步加载子节点,以提高性能。 6. 如果需要支持拖拽等交互功能,可以考虑使用第三方插件或库(如jQuery UI)。 希望这些建议对您有所帮助!
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。