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

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

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…...

(done) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)

网页&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html (任务1教会了你如何用 C 语言调用汇编&#xff0c;编译后链接即可) 任务1&#xff1a;Uthread: switching between threads (完成) 在这个练习中&#xff0c;你将设计一个用户级线程系统中的上下文切…...

大年初六,风很大

北京的风在立春附近的几天突然大了&#xff0c;正在盘算着这个冬天可能就这样平庸的去了&#xff0c;没成想风来了。走在风中&#xff0c;穿着本应该是三九天穿的冬装&#xff0c;紧闭着嘴&#xff0c;缩着身子&#xff0c;感受着这冬天该有的低温。这是冬天该有的样子&#xf…...

【算法】回溯算法专题③ ——排列型回溯 python

目录 前置小试牛刀回归经典举一反三总结 前置 【算法】回溯算法专题① ——子集型回溯 python 【算法】回溯算法专题② ——组合型回溯 剪枝 python 小试牛刀 全排列 https://leetcode.cn/problems/permutations/description/ 给定一个不含重复数字的数组 nums &#xff0c;返…...

利用deepseek参与软件测试 基本架构如何 又该在什么环节接入deepseek

利用DeepSeek参与软件测试&#xff0c;可以考虑以下基本架构和接入环节&#xff1a; ### 基本架构 - **数据层** - **测试数据存储**&#xff1a;用于存放各种测试数据&#xff0c;包括正常输入数据、边界值数据、异常数据等&#xff0c;这些数据可以作为DeepSeek的输入&…...

99.20 金融难点通俗解释:中药配方比喻马科维茨资产组合模型(MPT)

目录 0. 承前1. 核心知识点拆解2. 中药搭配比喻方案分析2.1 比喻的合理性 3. 通俗易懂的解释3.1 以中药房为例3.2 配方原理 4. 实际应用举例4.1 基础配方示例4.2 效果说明 5. 注意事项5.1 个性化配置5.2 定期调整 6. 总结7. 代码实现 0. 承前 本文主旨&#xff1a; 本文通过中…...

为AI聊天工具添加一个知识系统 之79 详细设计之20 正则表达式 之7

本文要点 要点 “正则表达式” 本来是计算机科学计算机科学的一个概念。本项目将它推广&#xff08;扩张&#xff09;到认知科学的“认知范畴”概念&#xff0c; 聚合&#xff08;收敛&#xff09;到 神经科学 的“神经元”概念。 做法是&#xff1a;用reg 来系统化定义认知…...

[ Spring ] Spring Boot Mybatis++ 2025

文章目录 StructureMyBatis Controller AbilitiesConfigure Plugins and RepositoriesApply Plugins and Add DependenciesMyBatis Spring PropertiesMyBatis ApplicationMyBatis BeansMyBatis MapperMyBatis Query Builder Structure this blog introduce 3 ways using mybat…...

虚幻基础17:动画层接口

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

前缀和算法

文章目录 算法总览题目1371.每个元音包含偶数次的最长子字符串 算法总览 题目 1371.每个元音包含偶数次的最长子字符串 1371.每个元音包含偶数次的最长子字符串 参考博主的讲解 思路分析&#xff1a;就是得使用前缀和记录情况&#xff0c;dp[i][j]表示s[0] 到s[i] 中&…...

稀疏混合专家架构语言模型(MoE)

注&#xff1a;本文为 “稀疏混合专家架构语言模型&#xff08;MoE&#xff09;” 相关文章合辑。 手把手教你&#xff0c;从零开始实现一个稀疏混合专家架构语言模型&#xff08;MoE&#xff09; 机器之心 2024年02月11日 12:21 河南 选自huggingface 机器之心编译 机器之心…...

深入理解 `box-sizing: border-box;`:CSS 布局的利器

深入理解 box-sizing: border-box;&#xff1a;CSS 布局的利器 默认行为示例代码 使用 box-sizing: border-box;示例代码 全局应用 box-sizing: border-box;示例代码 实际应用场景1. 表单布局2. 网格布局 总结 在 CSS 中&#xff0c;box-sizing 属性决定了元素的总宽度和高度是…...

MySQL不适合创建索引的11种情况

文章目录 前言1. **数据量小的表**2. **频繁更新的列**3. **低选择性的列**4. **频繁插入和删除的表**5. **查询中很少使用的列**6. **大文本或BLOB列**7. **复合索引中未使用的前导列**8. **频繁进行批量插入的表**9. **查询返回大部分数据的表**10. **临时表**11. **列值频繁…...

shell呈现数据——在脚本中重定向

重定向输出 只需简单地重定向相应的文件描述符&#xff0c;就可以在脚本中用文件描述符STDOUT和STDERR在多个位置生成输出。在脚本中重定向输出的方法有两种。 临时重定向每一行。永久重定向脚本中的所有命令。 下面将具体展示这两种方法的工作原理。 1.临时重定向 如果你…...

vector容器(详解)

本文最后是模拟实现全部讲解&#xff0c;文章穿插有彩色字体&#xff0c;是我总结的技巧和关键 1.vector的介绍及使用 1.1 vector的介绍 https://cplusplus.com/reference/vector/vector/&#xff08;vector的介绍&#xff09; 了解 1. vector是表示可变大小数组的序列容器。…...

【初/高中生讲机器学习】0. 本专栏 “食用” 指南——写在一周年之际⭐

创建时间&#xff1a;2025-01-27 首发时间&#xff1a;2025-01-29 最后编辑时间&#xff1a;2025-01-29 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名高一学生&#xff0c;热爱计…...

SAP SD学习笔记28 - 请求计划(开票计划)之2 - Milestone请求(里程碑开票)

上一章讲了请求计划&#xff08;开票计划&#xff09;中的 定期请求。 SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求-CSDN博客 本章继续来讲请求计划&#xff08;开票计划&#xff09;的其他内容&#xff1a; Milestone请求(里程碑请求)。 目录 1&#xff0c;Miles…...

【PyTorch介绍】

PyTorch 是什么&#xff1f; PyTorch 是一个开源的深度学习框架&#xff0c;由 Facebook 的人工智能研究实验室&#xff08;FAIR&#xff09;开发和维护。它是一个基于 Python 的库&#xff0c;专为深度学习和人工智能研究设计&#xff0c;支持动态计算图&#xff08;dynamic …...

语言月赛 202412【正在联系教练退赛】题解(AC)

》》》点我查看「视频」详解》》》 [语言月赛 202412] 正在联系教练退赛 题目背景 在本题中&#xff0c;我们称一个字符串 y y y 是一个字符串 x x x 的子串&#xff0c;当且仅当从 x x x 的开头和结尾删去若干个&#xff08;可以为 0 0 0 个&#xff09;字符后剩余的字…...

【C++】B2122 单词翻转

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 &#x1f4af;一、我的做法代码实现&#xff1a;代码解析思路分析 &#x1f4af;二、老师的第一种做法代码实现&a…...

redis基本数据结构

基本数据结构 String String是Redis中最常见的数据存储类型&#xff1a; 其基本编码方式是RAW&#xff0c;基于简单动态字符串&#xff08;SDS&#xff09;实现&#xff0c;存储上限为512mb。 如果存储的SDS长度小于44字节&#xff0c;则会采用EMBSTR编码&#xff0c;此时ob…...

基于STM32景区环境监测系统的设计与实现(论文+源码)

1系统方案设计 根据系统功能的设计要求&#xff0c;展开基于STM32景区环境监测系统设计。如图2.1所示为系统总体设计框图。系统以STM32单片机作为系统主控模块&#xff0c;通过DHT11传感器、MQ传感器、声音传感器实时监测景区环境中的温湿度、空气质量以及噪音数据。系统监测环…...

使用冒泡排序模拟实现qsort函数

1.冒泡排序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int arr[] { 0,2,5,3,4,8,9,7,6,1 };int sz sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i 0; i < sz - 1; i){//标志位&#xff0c;如果有序&#xff0c;直接…...

探秘Linux IO虚拟化:virtio的奇幻之旅

在当今数字化时代&#xff0c;虚拟化技术早已成为推动计算机领域发展的重要力量。想象一下&#xff0c;一台物理主机上能同时运行多个相互隔离的虚拟机&#xff0c;每个虚拟机都仿佛拥有自己独立的硬件资源&#xff0c;这一切是如何实现的呢&#xff1f;今天&#xff0c;就让我…...

在React中使用redux

一、首先安装两个插件 1.Redux Toolkit 2.react-redux 第一步&#xff1a;创建模块counterStore 第二步&#xff1a;在store的入口文件进行子模块的导入组合 第三步&#xff1a;在index.js中进行store的全局注入 第四步&#xff1a;在组件中进行使用 第五步&#xff1a;在组件中…...

从 C 到 C++:理解结构体中字符串的存储与操作

对于刚入门 C/C 的程序员来说&#xff0c;字符串的存储和操作可能是个容易混淆的知识点。在 C 中&#xff0c;std::string 提供了非常友好的接口&#xff0c;我们可以轻松地在结构体中使用字符串类型&#xff0c;无需关注底层细节。然而&#xff0c;在 C 语言中&#xff0c;字符…...

2.3学习总结

图&#xff1a; 1.图的基本概念 2.图的存储和遍历 3.最小生成树 4.最短路径 5.拓扑排序和关键路径 一、图的基本概念 图的定义&#xff1a;不允许没有顶点&#xff0c;但边集可以为空 {无向图 {有向图&#xff1a;边弧&#xff0c;弧头&#xff08;有箭头&#xff09;…...

wordpress代码结构解析

WordPress 是一个基于 PHP 和 MySQL 的开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;广泛用于构建网站和博客。要解析 WordPress 代码&#xff0c;首先需要了解其核心结构、主要文件和常用的函数。以下是 WordPress 代码解析的基本指南&#xff1a; --- ### 1. *…...

使用 Numpy 自定义数据集,使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测,对预测结果计算精确度和召回率及F1分数

1. 导入必要的库 首先&#xff0c;导入我们需要的库&#xff1a;Numpy、Pytorch 和相关工具包。 import numpy as np import torch import torch.nn as nn import torch.optim as optim from sklearn.metrics import accuracy_score, recall_score, f1_score2. 自定义数据集 …...

FPGA|例化生成的PLL功能IP核

1、例化上一篇文章中调用的IP核&#xff0c;新建文件PLL_test.v 2、代码如图 timescale 1ns / 1ps module PLL_test(input clk,input rst_n,output clkout0,output clkout1,output clkout2,output clkout3,output clkout4);wire locked;PLL pll_inst(.inclk0(clk),.c0(clkout0)…...

K个不同子数组的数目--滑动窗口--字节--亚马逊

Stay hungry, stay foolish 题目描述 给定一个正整数数组 nums和一个整数 k&#xff0c;返回 nums 中 「好子数组」 的数目。 如果 nums 的某个子数组中不同整数的个数恰好为 k&#xff0c;则称 nums 的这个连续、不一定不同的子数组为 「好子数组 」。 例如&#xff0c;[1,2,…...

手机连接WIFI可以上网,笔记本电脑连接WIFI却不能上网? 解决方法?

原因&#xff1a;DNS受污染了 解决办法 step 1&#xff1a;清空域名解析记录&#xff08;清空DNS&#xff09; ipconfig /flushdns (Windows cmd命令行输入) step 2&#xff1a;重新从DHCP 获取IP ipconfig /release&#xff08;释放当前IP地址&#xff09; ipconfig /renew &…...

大模型综述一镜到底(全文八万字) ——《Large Language Models: A Survey》

论文链接&#xff1a;https://arxiv.org/abs/2402.06196 摘要&#xff1a;自2022年11月ChatGPT发布以来&#xff0c;大语言模型&#xff08;LLMs&#xff09;因其在广泛的自然语言任务上的强大性能而备受关注。正如缩放定律所预测的那样&#xff0c;大语言模型通过在大量文本数…...

C语言按位取反【~】详解,含原码反码补码的0基础讲解【原码反码补码严格意义上来说属于计算机组成原理的范畴,不过这也是学好编程初级阶段的必修课】

目录 概述【适合0基础看的简要描述】&#xff1a; 上述加粗下划线的内容提取版&#xff1a; 从上述概述中提取的核心知识点&#xff0c;需背诵&#xff1a; 整数【包含整数&#xff0c;负整数和0】的原码反码补码相互转换的过程图示&#xff1a; 过程详细刨析&#xff1a;…...

本地部署与使用SenseVoice语音大模型简析

前言 SenseVoice 是一种语音基础模型&#xff0c;具有多种语音理解功能&#xff0c;包括自动语音识别 (ASR)、口语识别 (LID)、语音情感识别 (SER) 和音频事件检测 (AED)。本博客将指导您安装和使用 SenseVoice 模型&#xff0c;使其尽可能方便用户使用。 Github 仓库链接: ht…...

QMK启用摇杆和鼠标按键功能

虽然选择了触摸屏&#xff0c;我仍选择为机械键盘嵌入摇杆模块&#xff0c;这本质上是对"操作连续性"的执着。   值得深思的是&#xff0c;本次开发过程中借助DeepSeek的代码生成与逻辑推理&#xff0c;其展现的能力已然颠覆传统编程范式&#xff0c;需求描述可自动…...

排序算法与查找算法

1.十大经典排序算法 我们希望数据以一种有序的形式组织起来&#xff0c;无序的数据我们要尽量将其变得有序 一般说来有10种比较经典的排序算法 简单记忆为Miss D----D小姐 时间复杂度 &#xff1a;红色<绿色<蓝色 空间复杂度&#xff1a;圆越大越占空间 稳定性&…...

基于Spring Security 6的OAuth2 系列之九 - 授权服务器--token的获取

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security OAuth2搭建了网关和授权服务器&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级…...

【思维导图】redis

学习计划&#xff1a;将目前已经学的知识点串成一个思维导图。在往后的学习过程中&#xff0c;不断往思维导图里补充&#xff0c;形成自己整个知识体系。对于思维导图里的每个技术知识&#xff0c;自己用简洁的话概括出来&#xff0c; 训练自己的表达能力。...

【Git】使用笔记总结

目录 概述安装Git注册GitHub配置Git常用命令常见场景1. 修改文件2. 版本回退3. 分支管理 常见问题1. git add [中文文件夹] 无法显示中文问题2. git add [文件夹] 文件名中含有空格3. git add 触发 LF 回车换行警告4. git push 提示不存在 Origin 仓库5. Git与GitHub中默认分支…...

cf div3 998 E(并查集)

E : 给出两个简单无向图 &#xff08;没有重边和自环&#xff09;f g . 可以对f 进行 删边 和加边 的操作。问至少操作多少次 &#xff0c;使得 f 和 g 的 点的联通情况相同&#xff08;并查集的情况相同&#xff09; 首先思考删边 &#xff1a; 对于 我 f 图存在边 e &#x…...

【C++】string类(上):string类的常用接口介绍

文章目录 前言一、C中设计string类的意义二、string类的常用接口说明1. string类对象的常见构造2. string类对象的容量操作2.1 size、capacity 和 empty的使用2.2 clear的使用2.3 reserve的使用2.4 resize的使用 3. string类对象的访问及遍历操作3.1 下标[ ] 和 at3.2 迭代器it…...

[SAP ABAP] ABAP SQL跟踪工具

事务码ST05 操作步骤 步骤1&#xff1a;使用事务码ST05之前&#xff0c;将要检测的程序生成的页面先呈现出来&#xff0c;这里我们想看下面程序的取数操作&#xff0c;所以停留在选择界面 步骤2&#xff1a; 新建一个GUI窗口&#xff0c;输入事务码ST05&#xff0c;点击 Acti…...

OpenGL学习笔记(六):Transformations 变换(变换矩阵、坐标系统、GLM库应用)

文章目录 向量变换使用GLM变换&#xff08;缩放、旋转、位移&#xff09;将变换矩阵传递给着色器坐标系统与MVP矩阵三维变换绘制3D立方体 & 深度测试&#xff08;Z-buffer&#xff09;练习1——更多立方体 现在我们已经知道了如何创建一个物体、着色、加入纹理。但它们都还…...

PHP 常用函数2025.02

PHP implode() 函数 语法 implode(separator,array) 参数描述separator可选。规定数组元素之间放置的内容。默认是 ""&#xff08;空字符串&#xff09;。array必需。要组合为字符串的数组。 技术细节 返回值&#xff1a;返回一个由数组元素组合成的字符串。PHP 版…...

17.3.4 颜色矩阵

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 17.3.4.1 矩阵基本概念 矩阵&#xff08;Matrix&#xff09;是一个按照长方阵列排列的复数或实数集合&#xff0c;类似于数组。 由…...

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

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

02.04 数据类型

请写出以下几个数据的类型&#xff1a; 整数 a ----->int a的地址 ----->int* 存放a的数组b ----->int[] 存放a的地址的数组c ----->int*[] b的地址 ----->int* c的地址 ----->int** 指向printf函数的指针d ----->int (*)(const char*, ...) …...

WPS动画:使图形平移、围绕某个顶点旋转一定角度

1、平移 案例三角形如下图&#xff0c;需求&#xff1a;该三角形的A点平移至原点 &#xff08;1&#xff09;在预想动画结束的位置绘制出图形 &#xff08;2&#xff09;点击选中原始图像&#xff0c;插入/动画/绘制自定义路径/直线 &#xff08;3&#xff09;十字星绘制的直线…...

想表示消息返回值为Customer集合

道奈特(240***10) 14:34:55 EA中序列图。我想表示消息返回值为 Customer 集合。目前只有一个Customer实体类&#xff0c;我需要另外新建一个CustomerList 类吗&#xff1f; 潘加宇(35***47) 17:01:26 不需要。如果是分析&#xff0c;在类的操作中&#xff0c;定义一个参数&…...