当前位置: 首页 > article >正文

数据结构课程设计(四)校园导航

4 校园导航

4.1 需求规格说明

【问题描述】

一个学校平面图,至少包括10个以上的场所,每个场所带有编号、坐标、名称、类别等信息,两个场所间可以有路径相通,路长(耗时)各有不同。要求读取该校园平面图,查询各个场所信息,找出从任意场所到达另一场所的最短路径(最佳路径)。

【基本要求】

校园平面图用图数据结构表达,采用指令或菜单方式操作,实现场所查询和路径求解。

【提高要求】

编写图形用户界面程序,使用交互方式:1)绘制校园平面图,并加以存储;2)点选查询场所信息;3)点选起点和终点,显示求得的最佳路径。

【测试数据】

自行设计校园平面图,用数据文件存储,格式自定。

4.2 总体分析与设计

(1)设计思想

①存储结构

在解决校园导航的问题中,这里程序的图结构使用了殷人昆数据结构中的图结构作为模板,定义了顶点的数据类型 VertexData 结构体。指定模板的顶点数据类型为 VertexData,边上的权值类型为 float。定义使用该数据类 型的模板别名为 Edgef、Vertexf 和 Graphf。接着实现了 GraphAdjList 类,派生自 Graphf 类, 增加了相应函数方便快速查找。VertexData 结构体存储了顶点类型(可分为场所和路径,场所 拥有名称和类型而路径没有),索引,x 坐标、y 坐标,名称、类别等数据。此外,定义了结 构体 DjikstraPathsAndCost 负责存储顶点所对应最短路径的权值和所经过路径。

②主要算法思想

校园导航的核心数据结构为图结构,顶点表示校园中场所、或者路径点,边表示场所或者路径点之间的道路。每条边之间都有相应的权值,代表边的同行便利成程度。求解最短路径的核心算法为Dijkstra算法。该算法的核心思想为:

(1)指定一个起点顶点D。引进两个数组S和U。其中S的作用是记录已经求出的最短路径的顶点和经过路径以及距离顶点D的最短距离,U的作用是记录还未求出最短路径的顶点和经过路径以及距离顶点D的距离。

(2)初始化S和U集合。最初,S集合中只包含顶点D,U集合中包含除了顶点D以外的所有顶点。如果U中顶点和D不相邻,则距离为无穷大。

(3)从U集合中取出一个离顶点D距离最短的顶点K,将其加到数组S中。同时从U集合中移除顶点K。

(4)根据S集合中的路径更新U集合中每个顶点距离顶点D的最短距离和相应路径。

(5)重复(3)、(4)操作直到U集合为空。

(2)设计表示

校园导航构建的UML类图如图4.2-1所示。

4.2-2 程序UML类图

类Edgef、Vertexf和Graphf分别为Edge、Vertex、Graphlnk,均来自殷人昆数据结构中的图结构。

类CampusNavigationThread为算法的核心实现类。该类包含一个图GraphAdjList,函数LoadGraph负责读取图数据,SaveGraph负责保存平面图数据。核心算法函数为Dijkstra,接受一个起点在图中的索引位置,一个映射引用作为返回值。

类CampusNavigation为界面类,派生自QMainWindow,实现了相应的槽函数和绘制点、绘制、线等函数。核心为使用了QgraphicSence和CampusNavigationView进行显示。

类CampusNavigationView为视图类,派生自QGraphicsView,重写了其鼠标交互函数,负责获取鼠标在视图坐标系中的坐标并传递给主窗口。

(3)详细设计表示

校园导航构建的程序流程图如图4.2-2所示。

4.2-2 校园导航程序流程图

该程序的流程步骤如下所示:

1.初始化:声明一个数组dis来保存原点到各个顶点的最短距离,将起始节点的距离设为0,对于顶点s存在能直接到达的边(s,m),则把dis[m]设为w(s,m),同时把其他所有s不能直接到达的顶点的路径长度设为无穷大。创建一个空集合T,用于存储已经找到最短路径的节点。初始时,集合T只有起点S。

2.选择最近的节点:从未包含在T中的节点中,从dis数组选择最小值,即选择距离最短的节点,然后将其添加到T中。

3.更新距离:检查新添加的节点的所有邻接节点。如果通过新添加的节点到达邻接节点的距离小于比源点直接到达的距离,那么就更新这个距离。

4.重复步骤2和3:重复步骤2和3,直到集合T包含了图的所有节点。

迪杰斯特拉算法的优点是能够找到从起始节点到所有其他节点的最短路径,而且算法的时间复杂度相对较低。然而,需要注意的是,这个算法不能处理存在负权边的图。

4.3 编码

【问题1:对殷人昆数据结构中图模板的理解与应用以及修改?

【解决方式】:在阅读了殷人昆数据结构中图模板的源代码后,程序派生并修改了其图类。为了更加贴近校导航的真实场景,程序尝试定义场所点Site和路径点RoadNode,场所是具有实际意义的地点,路径点是进行同行的点。决定使用自定义性高的json数据表达校园平面图,分别存储场所、路径点以及边。在交互功能的实现中,交互过程中需要将窗口坐标转换为视图坐标,因此需要重写QgraphicView类。

【问题2】:为了提升用户体验,本导航精心设计了多种鼠标事件。然而,在某些情况下,这些事件可能会出现冲突,导致无法正常响应。

【解决方式】:在处理鼠标交互事件时,可以采用状态模式设计来解决不同状态下鼠标事件冲突的问题。状态模式设计包括编辑模式和导航模式两种状态。在编辑模式下,可以处理鼠标的点击、移动、双击事件,而在导航模式下,则可以处理鼠标的点击、移动事件,且拥有不同的响应。通过在不同的状态下处理不同的鼠标事件,可以有效地避免事件冲突的问题,用户使用更加友好。

【问题2】:QPainter绘制时点与线之间压盖,无法清除画布已经绘制的事件。

【解决方式】:首先,需要注意绘制的顺序。在绘制点与线时,需要先绘制线,再绘制点,这样可以保证点不会压在线上而导致无法清除已经绘制的事件。如果已经出现了压盖的情况,可以通过重绘事件来解决问题。重绘事件时需要注意保持绘制的顺序一致,否则可能会出现新的问题。

4.4 程序及算法分析

①使用说明

打开程序后,即可出现初始化程序样式,如图4.4-1所示。

4.4-1 初始化程序

这里可以点击“打开文件”,会弹出一个对话框选择文件路径,加载准备好的json数据。将将鼠标放置到红色个实心圆(场所点)上在左下角显示场所数据;点击“添加顶点”,在地图上点击即可添加顶点。点击后会弹出对话框选择顶点类型并输入相应数据。可以选择添加场所点或者路径点;点击“添加边”,选中两个顶点,若成功选中,则会弹出对话框输入权重;如图4.4-2所示。

4.4-2 详细操作流程

此外,程序还支持进行最短路径的查询操作,当点击“求解最短路径”时,在图上选中两个顶点,系统会自动求解两点之间的最短路径并使用蓝色线进行绘制。如图4.4-3所示。

4.4-3 求解最短路径

此外,程序还支持将输出的文件进行保存,当点击“保存”时,会弹出对话框选择保存路径,绘制好的平面图会以json格式保存,如图4.4-4所示。

4.4-4 保存文件

同时,为了考虑到界面的交互效果,这里还支持放大和缩小操作,均由QAction控件控制,如图4.4-5所示。

4.4-5 支持放大缩小

4.5 小结

本题的核心是求解最短路径,这是校园导航系统的关键所在。在众多求解最短路径的算法中,我选择了Dijkstra算法。原因在于此次题目要求的是校园导航,这是一个单源点正权图的问题,而Dijkstra算法正是针对这类问题设计的。它能够大大降低时间复杂度,提高求解效率。本导航系统以校园地图为基础,可以加载预先准备好的校园场所点和道路拐点数据。同时,用户也可以根据自己的需求编辑线路,使得系统的灵活性和拓展性得到了极大的提升。这使得我们能够真实模拟校园场景,包括各个路口的拐点。从而完成最短路径规划,为校园内的用户提供便捷、高效的导航服务。

为了提供更好的用户体验,本系统不仅具备编辑、导航功能,还注重用户交互体验的细节。多种鼠标事件的支持,对鼠标悬停、点击等行为进行细致处理,使得系统能够及时响应用户的操作,使得用户能够以更加自然、直观的方式与系统进行交互,极大地提升了用户的使用体验。多种信息展示方式,用户可以轻松获取校园场所点的详细信息,更好地了解校园的各项设施和服务。

但是,本题使用的算法需要遍历所有的节点,并在每一步都找到未访问的节点中距离最短的节点。如果节点的数量非常大,这个函数可能会比较慢。未来将采用更高效的实现,例如使用优先队列来存储未访问的节点。

4.6 附录

//实现点的插入
// 顶点数据结构
struct VertexData
{VertexType type = VertexType::None; // 顶点类型,默认为Noneint index = -1;                     // 数据索引float x = 0.0f;                            // 顶点的X坐标float y = 0.0f;                            // 顶点的Y坐标string name = "";                   // 顶点名称string category = "";               // 分类信息VertexData() {}                     // 默认构造函数VertexData(int) {}                  // 带参数构造函数(空实现)// 比较操作符重载,用于判断两个顶点数据是否相等bool operator==(const VertexData& other) const{return type == other.type&& index == other.index&& x == other.x&& y == other.y&& name == other.name&& category == other.category;}
};
//实现线的插入
// 图的邻接表表示类,继承自Graphlnk
class GraphAdjList : public Graphf
{
public:GraphAdjList(int sz) :Graphf(sz) {};	//构造函数~GraphAdjList() {};		//析构函数// 根据数据索引和类型获取顶点在邻接表中的位置int getVertexPosByDataIndex(int _index, VertexType type){for (int i = 0; i < numVertices; i++){if (NodeTable[i].data.type != type)continue;int index = NodeTable[i].data.index;if (index == _index)return i;}return -1;// 未找到对应顶点 }// 获取所有边的信息,返回一个包含起点、终点和权值的元组列表vector<tuple<int, int, float>> getEdges(){std::set<std::pair<int, int>> visitedEdges; // 用于跟踪已访问的边std::vector<std::tuple<int, int, float>> edges; // 存储边的信息for (int i = 0; i < numVertices; ++i){Edgef* edge = NodeTable[i].adj; // 当前顶点的邻接边表while (edge != nullptr){int u = i;              // 起点int v = edge->dest;     // 终点if (visitedEdges.find({ v, u }) == visitedEdges.end()){ // 如果这条边未被访问过visitedEdges.insert({ u, v }); // 标记为已访问edges.push_back({ u, v, edge->cost });}edge = edge->link; // 遍历下一条边}}return edges;}// 根据索引获取指定顶点的指针const Vertexf* getVertex(int index){if (index < 0 || index >= numVertices)return nullptr;return &NodeTable[index];}// 获取所有站点类型的顶点const vector<Vertexf*> getAllSiteVertexs(){vector<Vertexf*> vertexs;for (int i = 0; i < numVertices; i++){if (NodeTable[i].data.type == VertexType::Site){vertexs.push_back(&NodeTable[i]);}}return vertexs;}// 获取所有路节点类型的顶点const vector<Vertexf*> getAllRoadNodeVertexs(){vector<Vertexf*> vertexs;for (int i = 0; i < numVertices; i++){if (NodeTable[i].data.type == VertexType::RoadNode){vertexs.push_back(&NodeTable[i]);}}return vertexs;}// 获取站点数量int NumberOfSites(){int count = 0;for (int i = 0; i < numVertices; i++){if (NodeTable[i].data.type == VertexType::Site)count++;}return count;}// 获取路节点数量int NumberOfRoadNodes(){int count = 0;for (int i = 0; i < numVertices; i++){if (NodeTable[i].data.type == VertexType::RoadNode)count++;}return count;}// 获取图的边界矩形QRectF getBoundingRect(){float minX = std::numeric_limits<float>::max();float minY = std::numeric_limits<float>::max();float maxX = std::numeric_limits<float>::min();float maxY = std::numeric_limits<float>::min();for (int i = 0; i < numVertices; i++){float x = NodeTable[i].data.x;float y = NodeTable[i].data.y;if (x < minX)minX = x;if (x > maxX)maxX = x;if (y < minY)minY = y;if (y > maxY)maxY = y;}return QRectF(minX, minY, maxX - minX, maxY - minY);}
};
//实现Djikstra算法
bool CampusNavigationThread::Dijkstra(int startVertexIndex, map<int, DjikstraPathsAndCost>& S_vertexPosAndCost)
{if (startVertexIndex <  0 || startVertexIndex >= mGraph->NumberOfVertices())return false;map<int,DjikstraPathsAndCost> U_vertexPosAndCost;// 初始化U集合for (int i = 0; i < mGraph->NumberOfVertices(); i++){if(i==startVertexIndex)     //起点不加入U集合continue;float cost = mGraph->getWeight(startVertexIndex, i);DjikstraPathsAndCost pathAndCost;if(cost != -1)  // 顶点I和起点之间有边{pathAndCost.cost = cost;}else{pathAndCost.cost = std::numeric_limits<float>::max();}pathAndCost.pathIndex.push_back(i);U_vertexPosAndCost.insert(pair<int, DjikstraPathsAndCost>(i, pathAndCost));}// 初始化S集合DjikstraPathsAndCost startPathAndCost;startPathAndCost.cost = 0;startPathAndCost.pathIndex.push_back(startVertexIndex);S_vertexPosAndCost.insert(pair<int, DjikstraPathsAndCost>(startVertexIndex, startPathAndCost));while (!U_vertexPosAndCost.empty()){// 寻找U集合中权值最小的顶点Iauto minPos = min_element(U_vertexPosAndCost.begin(), U_vertexPosAndCost.end(),[](const pair<int, DjikstraPathsAndCost>& a, const pair<int, DjikstraPathsAndCost>& b) { return a.second.cost < b.second.cost; });S_vertexPosAndCost.insert(*minPos);        // 将权值最小的顶点I加入S集合float oldCost = minPos->second.cost;     // 起点到顶点I的距离vector<int> oldPath = minPos->second.pathIndex;  // 起点到顶点I的路径// 从U集合中移除顶点Iint minIndex = minPos->first;U_vertexPosAndCost.erase(minPos);// 更新U集合中的各顶点到起点的距离for (auto& K_pair : U_vertexPosAndCost){int i = K_pair.first;float minCost = K_pair.second.cost;float newCost = mGraph->getWeight(minIndex, i);     // 顶点K和顶点I之间的距离if (newCost == -1)  // 顶点K和顶点I之间没有边,保持原来的距离continue;newCost += oldCost;     // 顶点K到起点的距离if (newCost < minCost){K_pair.second.cost = newCost;K_pair.second.pathIndex = oldPath;K_pair.second.pathIndex.push_back(i);}}}return true;
}
//实现Djikstra算法
//将图的数据保存到JSON文件
bool CampusNavigationThread::SaveGraph(QString path)
{QJsonObject root;// 保存Sites数据QJsonArray sitesArray;const vector<Vertexf*> AllSites = mGraph->getAllSiteVertexs();for (const auto& site : AllSites){QJsonObject siteObject;siteObject["Index"] = site->data.index;siteObject["x"] = site->data.x;siteObject["y"] = site->data.y;siteObject["Name"] = QString::fromStdString(site->data.name);siteObject["Category"] = QString::fromStdString(site->data.category);sitesArray.append(siteObject);}root["Sites"] = sitesArray;// 保存 RoadNodes 数据QJsonArray roadNodesArray;const vector<Vertexf*> AllRoadNodes = mGraph->getAllRoadNodeVertexs();  // 获取所有路节点的顶点数据for (const auto& roadNode : AllRoadNodes){QJsonObject roadNodeObject;roadNodeObject["Index"] = roadNode->data.index;roadNodeObject["x"] = roadNode->data.x;roadNodeObject["y"] = roadNode->data.y;roadNodesArray.append(roadNodeObject);}root["RoadNodes"] = roadNodesArray;// 保存Edges数据QJsonArray edgesArray;vector<tuple<int, int, float>> edges = mGraph->getEdges();for (const auto& edge : edges){QJsonObject edgeObject;edgeObject["FromType"] = QString::fromStdString(getVertexTypeAsString(mGraph->getValue(std::get<0>(edge)).type));edgeObject["FromIndex"] = mGraph->getValue(std::get<0>(edge)).index;edgeObject["ToType"] = QString::fromStdString(getVertexTypeAsString(mGraph->getValue(std::get<1>(edge)).type));edgeObject["ToIndex"] = mGraph->getValue(std::get<1>(edge)).index;edgeObject["Cost"] = std::get<2>(edge);edgesArray.append(edgeObject);}root["Edges"] = edgesArray;// 将图数据保存为JSON数据QFile file(path);if (file.open(QIODevice::WriteOnly)){QJsonDocument jsonDoc(root);file.write(jsonDoc.toJson());file.close();return true;}else{return false;}
}

项目源代码:

Data-structure-coursework/4 at main · CUGLin/Data-structure-courseworkhttps://github.com/CUGLin/Data-structure-coursework/tree/main/4

相关文章:

数据结构课程设计(四)校园导航

4 校园导航 4.1 需求规格说明 【问题描述】 一个学校平面图&#xff0c;至少包括10个以上的场所&#xff0c;每个场所带有编号、坐标、名称、类别等信息&#xff0c;两个场所间可以有路径相通&#xff0c;路长&#xff08;耗时&#xff09;各有不同。要求读取该校园平面图&a…...

50【Windows与Linux】

大家可能有些人听过Linux系统&#xff0c;很多初学者被灌输的理念就是服务器必须要装Linux系统 什么是系统&#xff1f; 比如你的电脑是Windows系统的&#xff0c;你手机是Android系统的&#xff0c;物理设备都需要系统&#xff0c;系统你可以理解成直接控制物理设备的一个东…...

蓝桥杯python基础算法(2-2)——基础算法(D)——进制转换*

目录 五、进制转换 十进制转任意进制&#xff0c;任意进制转十进制 例题 P1230 进制转换 作业 P2095 进制转化 作业 P2489 进制 五、进制转换 十进制转任意进制&#xff0c;任意进制转十进制 int_to_char "0123456789ABCDEF" def Ten_to_K(k, x):answer "…...

CSS 溢出内容处理:从基础到实战

CSS 溢出内容处理&#xff1a;从基础到实战 1. 什么是溢出&#xff1f;示例代码&#xff1a;默认溢出行为 2. 使用 overflow 属性控制溢出2.1 使用 overflow: hidden 裁剪内容示例代码&#xff1a;裁剪溢出内容 2.2 使用 overflow: scroll 显示滚动条示例代码&#xff1a;显示滚…...

嵌入式知识点总结 操作系统 专题提升(四)-上下文

针对于嵌入式软件杂乱的知识点总结起来&#xff0c;提供给读者学习复习对下述内容的强化。 目录 1.上下文有哪些?怎么理解? 2.为什么会有上下文这种概念? 3.什么情况下进行用户态到内核态的切换? 4.中断上下文代码中有哪些注意事项&#xff1f; 5.请问线程需要保存哪些…...

Elasticsearch基本使用详解

文章目录 Elasticsearch基本使用详解一、引言二、环境搭建1、安装 Elasticsearch2、安装 Kibana&#xff08;可选&#xff09; 三、索引操作1、创建索引2、查看索引3、删除索引 四、数据操作1、插入数据2、查询数据&#xff08;1&#xff09;简单查询&#xff08;2&#xff09;…...

携程Android开发面试题及参考答案

在项目中,给别人发的动态点赞功能是如何实现的? 数据库设计:首先要在数据库中为动态表添加一个点赞字段,用于记录点赞数量,同时可能需要一个点赞关系表,记录用户与动态之间的点赞关联,包括点赞时间等信息。界面交互:在 Android 界面上,为点赞按钮设置点击事件监听器。…...

xxl-job 在 Java 项目的使用 以一个代驾项目中的订单模块举例

能搜到这里的最起码一定知道 xxl-job 是用来干什么的&#xff0c;我就不多啰嗦怎么下载以及它的历史了 首先我们要知道 xxl-job 这个框架的结构&#xff0c;如下图&#xff1a; xxl-job-master&#xff1a;xxl-job-admin&#xff1a;调度中心xxl-job-core&#xff1a;公共依赖…...

Alibaba开发规范_异常日志之日志规约:最佳实践与常见陷阱

文章目录 引言1. 使用SLF4J日志门面规则解释代码示例正例反例 2. 日志文件的保存时间规则解释 3. 日志文件的命名规范规则解释代码示例正例反例 4. 使用占位符进行日志拼接规则解释代码示例正例反例 5. 日志级别的开关判断规则解释代码示例正例反例 6. 避免重复打印日志规则解释…...

【数据分析】案例03:当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib)

当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib) 当当网近30日热销书籍官网写在前面 实验目的:实现当当网近30日热销图书的数据采集与可视化分析。 电脑系统:Windows 使用软件:Visual Studio Code Python版本:python 3.12.4 技术需求:scrapy、…...

需求分析应该从哪些方面来着手做?

需求分析一般可从以下几个方面着手&#xff1a; 业务需求方面 - 与相关方沟通&#xff1a;与业务部门、客户等进行深入交流&#xff0c;通过访谈、问卷调查、会议讨论等方式&#xff0c;明确他们对项目的期望、目标和整体业务需求&#xff0c;了解项目要解决的业务问题及达成的…...

申博经验贴

1. 所谓申博&#xff0c;最重要的就是定制的海投 分成两个部分 1. 定制 要根据每个教授去写不同的&#xff0c;一定不要泛泛的去写&#xff0c;一定要非常非常的具体&#xff0c;要引起教授的兴趣。每个教授每天都会收到几十封邮件&#xff0c;所以要足够的引起教授的注意&a…...

SpringAI 人工智能

随着 AI 技术的不断发展&#xff0c;越来越多的企业开始将 AI 模型集成到其业务系统中&#xff0c;从而提升系统的智能化水平、自动化程度和用户体验。在此背景下&#xff0c;Spring AI 作为一个企业级 AI 框架&#xff0c;提供了丰富的工具和机制&#xff0c;可以帮助开发者将…...

虚幻基础17:动画层接口

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 animation layer interface animation layer interface 动画层接口&#xff1a;动画图表的集。仅有名字。 添加到动画蓝图中&#xff0c;由动画蓝图实现动画图表。...

SQLAlchemy 2.0的简单使用教程

SQLAlchemy 2.0相比1.x进行了很大的更新&#xff0c;目前网上的教程不多&#xff0c;以下以链接mysql为例介绍一下基本的使用方法 环境及依赖 Python:3.8 mysql:8.3 Flask:3.0.3 SQLAlchemy:2.0.37 PyMySQL:1.1.1使用步骤 1、创建引擎&#xff0c;链接到mysql engine crea…...

Codeforces Round 1002 (Div. 2) A-D

复活&#xff01;年后首场&#xff01;本期封面是我自己AI弄的图 A - Milya and Two Arrays 题意 给两个所有数字出现次数都大于2的数组&#xff0c;问能不能修改排序之后对应位置相加得到新的数组使不同数字个数达到3 思路 直接计数就行了&#xff0c;不同的数字匹配一下…...

OpenGL学习笔记(七):Camera 摄像机(视图变换、LookAt矩阵、Camera类的实现)

文章目录 摄像机/观察空间/视图变换LookAt矩阵移动相机&#xff08;处理键盘输入&#xff09;移动速度欧拉角移动视角&#xff08;处理鼠标输入&#xff09;缩放场景&#xff08;处理滚轮输入&#xff09;Camera类 摄像机/观察空间/视图变换 在上一节变换中&#xff0c;我们讨…...

『VUE』vue-quill-editor富文本编辑器添加按钮houver提示(详细图文注释)

目录 预览效果新建一个config.js存放标题编写添加提示的方法调用添加标题方法的生命周期总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 预览效果 新建一个config.js存放标题 export const titleConfig [{ Choice: .ql-bold…...

如何使用 DeepSeek 和 Dexscreener 构建免费的 AI 加密交易机器人?

我使用DeepSeek AI和Dexscreener API构建的一个简单的 AI 加密交易机器人实现了这一目标。在本文中&#xff0c;我将逐步指导您如何构建像我一样的机器人。 DeepSeek 最近发布了R1&#xff0c;这是一种先进的 AI 模型。您可以将其视为 ChatGPT 的免费开源版本&#xff0c;但增加…...

Kafka流式计算架构

引言 Kafka 凭借其卓越的架构设计&#xff0c;具备极为高效的流式计算能力&#xff0c;在海量数据环境下&#xff0c;依然能够以惊人的速度实现消息的高性能消费&#xff0c;轻松应对高并发、低延迟的严苛业务需求。无论是实时数据处理、复杂事件分析&#xff0c;还是大规模数…...

C++泛型编程06(默认模板实参)

文章目录 1.4 默认模板实参 (Default Template Arguments)示例&#xff1a;灵活定义返回类型 当然&#xff0c;这里是对关于默认模板实参(Default Template Arguments)的内容进行了改进和优化后的叙述&#xff1a; 1.4 默认模板实参 (Default Template Arguments) 在C中&…...

微信登录模块封装

文章目录 1.资质申请2.combinations-wx-login-starter1.目录结构2.pom.xml 引入okhttp依赖3.WxLoginProperties.java 属性配置4.WxLoginUtil.java 后端通过 code 获取 access_token的工具类5.WxLoginAutoConfiguration.java 自动配置类6.spring.factories 激活自动配置类 3.com…...

SRS代码目录

代码目录&#xff1a; src/目录下核心代码&#xff1a; core&#xff1a;核心功能模块&#xff0c;包括日志、配置、错误处理等&#xff1b;protocol&#xff1a;实现RTMP、HTTP-FLV、HLS等协议的模块&#xff1b;app&#xff1a;应用层的实现&#xff0c;包括流的发布、播放…...

C++STL(一)——string类

目录 一、string的定义方式二、 string类对象的容量操作三、string类对象的访问及遍历操作四、string类对象的修改操作五、string类非成员函数 一、string的定义方式 string是个管理字符数组的类&#xff0c;其实就是字符数组的顺序表。 它的接口也是非常多的。本章介绍一些常…...

机器学习--1.KNN机器学习入门

1、机器学习概述 1.1、什么是机器学习 机器学习&#xff08;Machine Learning&#xff09;是人工智能&#xff08;Artificial Intelligence&#xff09;领域的一个子集&#xff0c;它主要关注如何让计算机系统通过经验学习&#xff08;数据&#xff09;并自动改进性能。机器学…...

Adaptive LLM Transformer²

看到了一个不错的论文https://arxiv.org/pdf/2501.06252 TRANSFORMER-SQUARED: SELF-ADAPTIVE LLMS 挺有意思的&#xff0c;是一家日本AI公司SakanaAI的论文&#xff08;我以前写过他们的不训练提升模型的能力的文章&#xff0c;感兴趣可以去翻&#xff09;它家有Lion Jones坐镇…...

三路排序算法

三路排序算法 引言 排序算法是计算机科学中基础且重要的算法之一。在数据分析和处理中&#xff0c;排序算法的效率直接影响着程序的执行速度和系统的稳定性。本文将深入探讨三路排序算法&#xff0c;包括其原理、实现和应用场景。 一、三路排序算法的原理 三路排序算法是一…...

代码随想录day27

669. /** lc appleetcode.cn id669 langcpp** [669] 修剪二叉搜索树*/// lc codestart /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}…...

基于LabVIEW的Modbus-RTU设备通信失败问题分析与解决

在使用 LabVIEW 通过 Modbus-RTU 协议与工业设备进行通信时&#xff0c;可能遇到无法正常发送或接收指令的问题。常见原因包括协议参数配置错误、硬件连接问题、数据帧格式不正确等。本文以某 RGBW 控制器调光失败为例&#xff0c;提出了一种通用的排查思路&#xff0c;帮助开发…...

1. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--前言

在我们的专栏《单体开发》中&#xff0c;我们实现了一个简单的记账软件的服务端&#xff0c;并且成功上线。随着用户数量的不断增长&#xff0c;问题逐渐开始显现。访问量逐渐增加&#xff0c;服务端的压力也随之加大。随着访问量的攀升&#xff0c;服务端的响应时间变得越来越…...