尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
高阶数据结构(C++)
一、并查集1.并查集原理在一些应用问题中需要将n个不同的元素划分成一些不相交的集合。开始时每个元素自成一个 单元素集合然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一 个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find set)。像堆类似用下标表示关系双亲表示法补充表示初始状态给的是-1表示10颗树。从上图可以看出编号6,7,8同学属于0号小分队该小分队中有4人(包含队长0)编号为4和9的同 学属于1号小分队该小分队有3人(包含队长1)编号为3和5的同学属于2号小分队该小分队有3 个人(包含队长1)。特点一个位置值是负数那他就是树的根这个负数的绝对值就是这棵树数据个数一个位置的值是正数那他就是双亲的下标仔细观察数组中内融化可以得出以下结论数组的下标对应集合中元素的编号数组中如果为负数负号代表根数字代表该集合中元素个数数组中如果为非负数代表该元素双亲在数组中的下标在公司工作一段时间后西安小分队中8号同学与成都小分队1号同学奇迹般的走到了一起两个小圈子的学生相互介绍最后成为了一个小圈子现在0集合有7个人2集合有3个人总共两个朋友圈。通过以上例子可知并查集一般可以解决一下问题1. 查找元素属于哪个集合沿着数组表示树形关系以上一直找到根(即树中中元素为负数的位置)2. 查看两个元素是否属于同一个集合沿着数组表示的树形关系往上一直找到树的根如果根相同表明在同一个集合否则不在3. 将两个集合归并成一个集合将两个集合中的元素合并 将一个集合名称改成另一个集合的名称4. 集合的个数遍历数组数组中元素为负数的个数即为集合的个数。2.并查集实现class UnionFindSet { public: UnionFindSet(size_t n) :_ufs(n, -1) {} //合并 void Union(int x1, int x2) { int root1 FindRoot(x1); int root2 FindRoot(x2); //如果本身就在一个集合就没必要合并 if (root1 root2) return; //数据量小的往大的合并 if (abs(_ufs[root1]) abs(_ufs[root2])) { swap(root1, root2); } _ufs[root1] _ufs[root2]; _ufs[root2] root1; } //找根 int FindRoot(int x) { int root x; while (_ufs[root] 0) { root _ufs[root]; } //路径压缩 while (_ufs[x] 0) { int parent _ufs[x]; _ufs[x] root; x parent; } return root; } //判断x1和x2是否在同一个集合 bool InSet(int x1 , int x2) { return FindRoot(x1) FindRoot(x2); } //集合数 size_t SetSize() { size_t size 0; for (int i 0; i _ufs.size(); i) { if (_ufs[i] 0) { size; } } return size; } private: vectorint _ufs; };3.并查集应用3.1 省份数量leetcode116. 省份数量leetcode代码实现如下(法一并查集)class UnionFindSet { public: UnionFindSet(size_t n) :_ufs(n, -1) {} //合并 void Union(int x1, int x2) { int root1 FindRoot(x1); int root2 FindRoot(x2); //如果本身就在一个集合就没必要合并 if (root1 root2) return; if (root1 root2) { swap(root1, root2); } _ufs[root1] _ufs[root2]; _ufs[root2] root1; } //找根 int FindRoot(int x) { int parent x; while (_ufs[parent] 0) { parent _ufs[parent]; } return parent; } //判断x1和x2是否在同一个集合 bool InSet(int x1 , int x2) { return FindRoot(x1) FindRoot(x2); } //集合数 size_t SetSize() { size_t size 0; for (int i 0; i _ufs.size(); i) { if (_ufs[i] 0) { size; } } return size; } private: vectorint _ufs; }; class Solution { public: int findCircleNum(vectorvectorint isConnected) { UnionFindSet ufs(isConnected.size()); for(size_t i 0 ; i isConnected.size();i) { for(int j 0;jisConnected[i].size();j) { if(isConnected[i][j] 1) { ufs.Union(i,j); } } } return ufs.SetSize(); } };代码实现二class Solution { public: int findCircleNum(vectorvectorint isConnected) { vectorint ufs(isConnected.size(),-1); auto findRoot [ufs](int x) { while(ufs[x] 0) x ufs[x]; return x; }; for(int i 0;iisConnected.size();i) { for(int j 0;jisConnected[i].size();j) { if(isConnected[i][j] 1) { //合并集合 int root1 findRoot(i); int root2 findRoot(j); if(root1 ! root2) { ufs[root1] ufs[root2]; ufs[root2] root1; } } } } int n 0; for(auto e:ufs) { if(e 0) n; } return n; } };3.2 等式方程的可满足性leetcode990. 等式方程的可满足性 - 力扣LeetCode代码实现如下class Solution { public: bool equationsPossible(vectorstring equations) { vectorint ufs(26,-1); auto finRoot [ufs](int x) { while(ufs[x] 0) x ufs[x]; return x; }; //第一遍先把相等的值加到一个集合中 for(auto str : equations) { if(str[1] ) { int root1 finRoot(str[0] - a); int root2 finRoot(str[3] - a); if(root1 ! root2) { ufs[root1] ufs[root2]; ufs[root2] root1; } } } //第二遍不相等的在不在一个集合在就相悖了 //返回false for(auto str : equations) { if(str[1] !) { int root1 finRoot(str[0] - a); int root2 finRoot(str[3] - a); if(root1 root2) { return false; } } } return true; } };二、图1. 图的基本概念图是由顶点集合及顶点间的关系组成的一种数据结构G (V E)其中补充Ggraph图Vvertex顶点Eedge边顶点集合V {x|x属于某个数据对象集}是有穷非空集合。边的集合E {(x,y)|x,y属于V}或者E {x,y|x,y属于V Path(x, y)}是顶点间关系的有穷集 合。说明(x, y)表示x到y的一条双向通路即(x, y)是无方向的Path(x, y)表示从x到y的一条单向通路即Path(x, y)是有方向的。树是一种特殊无环连通的图图不一定是树注意树关注的节点顶点中存的值图关注的是顶点及边的权值顶点和边图中结点称为顶点第i个顶点记作。两个顶点和相关联称作顶点和顶点之间 有一条边图中的第k条边记作ek或。有向图和无向图在有向图中顶点对x,y是有序的顶点对x,y称为顶点x到顶点y的一条边(弧)x,y和y,z是两条不同的边比如下图G3和G4为有向图。在无向图中顶点对(x, y) 是无序的顶点对(x,y)称为顶点x和顶点y相关联的一条边这条边没有特定方向(x, y)和(yx) 是同一条边比如下图G1和G2为无向图。注意无向边(x, y)等于有向边x,y和y,x。完全图在有n个顶点的无向图中若有n * (n-1)/2条边即任意两个顶点之间有且仅有一条边 则称此图为无向完全图比如上图G1在n个顶点的有向图中若有n * (n-1)条边即任意两个顶点之间有且仅有方向相反的边则称此图为有向完全图比如上图G4。邻接顶点在无向图中G中若(u, v)是E(G)中的一条边则称u和v互为邻接顶点并称边(u,v)依附于顶点u和v在有向图G中若u,v是E(G)中的一条边则称顶点u邻接到v顶点v邻接自顶点u并称边与顶点u和顶点v相关联。顶点的度顶点v的度是指与它相关联的边的条数记作deg(v)。在有向图中顶点的度等于该顶 点的入度与出度之和顶点v的入度是以v为终点的有向边的条数记作indev(v)顶点v的出度是以v为起点的有向边的条数记作outdev(v)因此dev(v) indev(v) outdev(v)。注 意对于无向图顶点的度等于该顶点的入度和出度即dev(v) indev(v) outdev(v)。路径在图G (V E)中若从顶点vi出发有一组边使其可到达顶点vj则称顶点vi到顶点vj的顶 点序列为从顶点vi到顶点vj的路径。路径长度对于不带权的图一条路径的路径长度是指该路径上的边的条数对于带权的图一 条路径的路径长度是指该路径上各个边权值的总和。权值边附带的数据信息。简单路径与回路若路径上各顶点v1v2v3…vm均不重复则称这样的路径为简单路径。若路 径上第一个顶点v1和最后一个顶点vm重合则称这样的路径为回路或环。子图设图G {V, E}和图G1 {V1E1}若V1属于V且E1属于E则称G1是G的子图。无向图有向图连通图在无向图中若从顶点v1到顶点v2有路径则称顶点v1与顶点v2是连通的。如果图中任 意一对顶点都是连通的则称此图为连通图。强连通图在有向图中若在每一对顶点vi和vj之间都存在一条从vi到vj的路径也存在一条从vj 到 vi的路径则称此图是强连通图。生成树无向图一个连通图的最小连通子图称作该图的生成树。有n个顶点的连通图的生成树有n个顶点 和n - 1条边。2. 图的存储结构因为图中既有节点又有边(节点与节点之间的关系)因此在图的存储中只需要保存节点和 边关系即可。2.1 邻接矩阵因为节点与节点之间的关系就是连通与否即为0或者1因此邻接矩阵(二维数组)即是先用一个数组将定点保存然后采用矩阵来表示节点与节点之间的关系。无向图的邻接矩阵是对称矩阵。注意无向图的邻接矩阵是对称的第 i 行(列)元素之和就是顶点 i 的度。有向图的邻接矩阵则不一 定是对称的第 i 行(列)元素之后就是顶点 i 的出(入)度。如果边带有权值并且两个节点之间是连通的上图中的边的关系就用权值代替如果两个顶点不通则使用无穷大代替。用邻接矩阵存储图的要点是能够快速知道两个顶点是否连通缺陷是如果顶点比较多边比较少时矩阵中存储了大量的0成为系数矩阵比较浪费空间并且要求两个节点之间的路径不是很好求。邻接矩阵的优点:邻接矩阵存储方式非常适合稠密图。邻接矩阵O(1)判断两个顶点的连接关系并取到权值。邻接矩阵的缺点相对而言不适合用来查找一个顶点连接的所有边。——O(N)代码实现namespace matrix { //vertex边 weight权值 false表示无向图true表示有向图 templateclass V, class W, W MAX_W INT_MAX , bool Direction false class Graph { public: //图的创建 //1, IO输入 ---不方便测试oj中更适合 //2图结构关系写到文件读取文件 //3手动添加边 Graph(const V* a, size_t n) { _vertexs.reserve(n); for (size_t i 0; i n; i) { _vertexs.push_back(a[i]); _indexMap[a[i]] i; } _matrix.resize(n); for (int i 0; i _matrix.size(); i) { _matrix[i].resize(n, MAX_W); } } size_t GetVertexIndex(const V v) { auto it _indexMap.find(v); if (it ! _indexMap.end()) { return it-second; } else { assert(false); return -1; } } void AddEdge(const V src, const V dst, const W w) { size_t srci GetVertexIndex(src); size_t dsti GetVertexIndex(dst); _matrix[srci][dsti] w; //无向图 if (Direction false) { _matrix[dsti][srci] w; } } void Print() { // 顶点 for (size_t i 0; i _vertexs.size(); i) { cout [ i ] - _vertexs[i] endl; } cout endl; //矩阵 for (int i 0; i _matrix.size(); i) { for (int j 0; j _matrix[i].size(); j) { if (_matrix[i][j] INT_MAX) { cout ∞ ; } else { cout _matrix[i][j] ; } } cout endl; } cout endl; } private: vectorV _vertexs; //顶点集合 mapV, int _indexMap; //顶点映射的下标 vectorvectorW _matrix; //邻接矩阵 }; void TestGraph() { Graphchar, int, INT_MAX, true g(0123, 4); g.AddEdge(0, 1, 1); g.AddEdge(0, 3, 4); g.AddEdge(1, 3, 2); g.AddEdge(1, 2, 9); g.AddEdge(2, 3, 8); g.AddEdge(2, 1, 5); g.AddEdge(2, 0, 3); g.AddEdge(3, 2, 6); g.Print(); } }2.2 邻接表邻接表使用数组表示顶点的集合使用链表表示边的关系。1. 无向图邻接表存储注意无向图中同一条边在邻接表中出现了两次。如果想知道顶点vi的度只需要知道顶点 vi边链表集合中结点的数目即可。2. 有向图邻接表存储一般情况下有向图存储一个出边表即可。注意有向图中每条边在邻接表中只出现一次与顶点vi对应的邻接表所含结点的个数就 是该顶点的出度也称出度表要得到vi顶点的入度必须检测其他所有顶点对应的边链 表看有多少边顶点的dst取值是i。邻接表优点适合存储稀疏图。适合查找一个顶点连接出去的边邻接表缺点不适合确定两个顶点是否相连及权值代码实现如下//邻接表 namespace link_table { templateclass W struct Edge { int _dsti; //目标点的下标 W _w; //权值 EdgeW* _next; Edge(int dsti, const W w) :_dsti(dsti) , _w(w) ,_next(nullptr) {} }; //vertex边 weight权值 false表示无向图true表示有向图 templateclass V, class W, bool Direction false class Graph { typedef EdgeW Edge; public: Graph(const V* a, size_t n) { _vertexs.reserve(n); for (size_t i 0; i n; i) { _vertexs.push_back(a[i]); _indexMap[a[i]] i; } _tables.resize(n, nullptr); } size_t GetVertexIndex(const V v) { auto it _indexMap.find(v); if (it ! _indexMap.end()) { return it-second; } else { assert(false); return -1; } } void AddEdge(const V src, const V dst, const W w) { size_t srci GetVertexIndex(src); size_t dsti GetVertexIndex(dst); //1-2 //头插 Edge* eg new Edge(dsti,w); eg-_next _tables[srci]; _tables[srci] eg; //2-1 if (Direction false) //无向表 { Edge* eg new Edge(srci, w); eg-_next _tables[dsti]; _tables[dsti] eg; } } void Print() { // 顶点 for (size_t i 0; i _vertexs.size(); i) { cout [ i ] - _vertexs[i] endl; } cout endl; for (int i 0; i _tables.size(); i) { cout _vertexs[i] [ i ]-; Edge* cur _tables[i]; while (cur) { cout _vertexs[cur-_dsti] [ cur-_dsti ]cur-_w-; cur cur-_next; } cout null endl; } } private: vectorV _vertexs; //顶点集合 mapV, int _indexMap; //顶点映射的下标 vectorEdge* _tables; //邻接表 }; void TestGraph() { //Graphchar, int, INT_MAX, true g(0123, 4); //g.AddEdge(0, 1, 1); //g.AddEdge(0, 3, 4); //g.AddEdge(1, 3, 2); //g.AddEdge(1, 2, 9); //g.AddEdge(2, 3, 8); //g.AddEdge(2, 1, 5); //g.AddEdge(2, 0, 3); //g.AddEdge(3, 2, 6); //g.Print(); string a[] { 张三, 李四, 王五, 赵六 }; Graphstring, int,true g1(a, 4); g1.AddEdge(张三, 李四, 100); g1.AddEdge(张三, 王五, 200); g1.AddEdge(王五, 赵六, 30); g1.Print(); } }总结邻接矩阵和邻接表其实属于相辅相成各有优缺点的互补结构3. 图的遍历给定一个图G和其中任意一个顶点v0从v0出发沿着图中各边访问图中的所有顶点且每个顶点仅被遍历一次。遍历即对结点进行某种操作的意思。3.1 图的广度优先遍历代码实现使用的邻接矩阵void BFS(const V src) { int srci GetVertexIndex(src); //队列和标记数组 queueint q; vectorbool visited(_vertexs.size(), false); q.push(srci); visited[srci] true; int levelSize 1; while (!q.empty()) { //一层一层出 for (int i 0; i levelSize; i) { int front q.front(); cout front : _vertexs[front] ; q.pop(); //把front顶点的邻接顶点入队列 for (int i 0; i _matrix.size(); i) { if (visited[i] false _matrix[front][i] ! MAX_W) { q.push(i); visited[i] true; } } } cout endl; levelSize q.size(); } }3.2 图的深度优先遍历代码实现如下void _DFS(int srci, vectorbool visited) { cout srci : _vertexs[srci] endl; visited[srci] true; //找一个srci相邻的没有访问过点去往深度遍历 for (int i 0;i_vertexs.size();i) { if (_matrix[srci][i] ! MAX_W visited[i] false) { _DFS(i, visited); } } } void DFS(const V src) { int srci GetVertexIndex(src); vectorbool visited(_vertexs.size(),false); _DFS(srci,visited); }4.最小生成树连通图中的每一棵生成树都是原图的一个极大无环子图即从其中删去任何一条边生成树就不在连通反之在其中引入任何一条新边都会形成一条回路。若连通图由n个顶点组成则其生成树必含n个顶点和n-1条边。因此构造最小生成树的准则有三条只能使用图中权值最小的边来构造最小生成树只能使用恰好n-1条边来连接图中的n个顶点选用的n-1条边不能构成回路构造最小生成树的方法Kruskal算法和Prim算法。这两个算法都采用了逐步求解的贪心策略。最小生成树构成生成树这些边加起来权值是最小的。最小的成本使N个顶点连接起来贪心算法是指在问题求解时总是做出当前看起来最好的选择。也就是说贪心算法做出的不是 整体最优的的选择而是某种意义上的局部最优解。贪心算法不是对所有的问题都能得到整体最优解。4.1 Kruskal算法任给一个有n个顶点的连通网络N{V,E}首先构造一个由这n个顶点组成、不含任何边的图G{V,NULL}其中每个顶点自成一个连通分量 其次不断从E中取出权值最小的一条边(若有多条任取其一)若该边的两个顶点来自不同的连通分量则将此边加入到G中。如此重复直到所有顶点在同一个连通分量上为止。核心每次迭代时选出一条具有最小权值且两端点不在同一连通分量上的边加入生成树。判环 —— 利用并查集代码实现如下typedef GraphV, W, MAX_W, Direction Self; //Kruskal算法 struct Edge { int _srci; int _dsti; W _w; Edge(int srci,int dsti,const W w) :_srci(srci) ,_dsti(dsti) ,_w(w) {} bool operator( const Edge e) const { return _w e._w; } }; W Kruskal(Self minTree) { int n _vertexs.size(); minTree._vertexs _vertexs; minTree._indexMap _indexMap; minTree._matrix.resize(n); for (int i 0; i n; i) { minTree._matrix[i].resize(n,MAX_W); } //优先级队列 priority_queueEdge , vectorEdge,greaterEdge minque; //将全部边放入优先级队列一定是无向图 for (int i 0; i n; i) { for (int j 0; j n; j) { if (ij _matrix[i][j] ! MAX_W) { minque.push(Edge(i, j, _matrix[i][j])); } } } //选出n-1条边 int size 0; W totalW W(); UnionFindSet ufs(n); while (!minque.empty()) { Edge min minque.top(); minque.pop(); if (!ufs.InSet(min._srci, min._dsti)) { minTree.AddEdge(min._srci, min._dsti, min._w); ufs.Union(min._srci, min._dsti); size; totalW min._w; } else { cout 构成环:; } } if (size n - 1) { return totalW; } else { return W(); } }4.2 Prim算法与Kruskal算法类似Prim算法也是通用的最小生成树的一个特例。Prim算法的工作原理与Dijkstra的最短路径算法相似。Prim算法所具有的一个性质是集合A中的边构成一棵树。这棵树从一个任意的跟节点r开始一直长大到覆盖V中的所有结点时为止。如下图所示代码实现如下//Prim算法 W Prim(Self minTree,const V src) { int srci GetVertexIndex(src); int n _vertexs.size(); //初始化 minTree._vertexs _vertexs; minTree._indexMap _indexMap; minTree._matrix.resize(n); for (int i 0; i n; i) { minTree._matrix[i].resize(n, MAX_W); } //创建两个集合 vectorbool X(n,false); vectorbool Y(n,true); X[srci] true; Y[srci] false; //从X-Y集合中连接的边里面选出最小的边 priority_queueEdge, vectorEdge, greaterEdge minq; //先把srci连接的边添加到队列中 for (int i 0; i n; i) { if (_matrix[srci][i] ! MAX_W) { minq.push(Edge(srci,i, _matrix[srci][i])); } } int i 0; W totalw W(); while (!minq.empty()) { Edge min minq.top(); minq.pop(); //最小边的目标点也在X集合则构成环 if (X[min._dsti]) { //cout 形成了环 endl; } else { minTree.AddEdge(min._srci, min._dsti, min._w); X[min._dsti] true; Y[min._dsti] false; i; totalw min._w; if (i n - 1) break; for (int i 0; i n; i) { if (_matrix[min._dsti][i] ! MAX_W Y[i]) { minq.push(Edge(min._dsti, i, _matrix[min._dsti][i])); } } } } if (i n - 1) { return totalw; } else { return W(); } }5.最短路径最短路径问题从在带权有向图G中的某一顶点出发找出一条通往另一顶点的最短路径最短也就是 沿路径各边的权值总和达到最小。5.1 单源最短路径--Dijkstra算法单源最短路径问题给定一个图G ( V E ) G(VE)G(VE)求源结点s ∈ V s∈Vs∈V到图中每个结点v ∈ V v∈Vv∈V的最短路径。Dijkstra算法就适用于解决带权重的有向图上的单源最短路径问题同时算法要求图中所有边的权重非负。一般在求解最短路径的时候都是已知一个起点和一个终点所以使用Dijkstra算法求解过后也就得到了所需起点到终点的最短路径。针对一个带权有向图G将所有结点分为两组S和QS是已经确定最短路径的结点集合在初始时 为空初始时就可以将源节点s放入毕竟源节点到自己的代价是0Q为其余未确定最短路径 的结点集合每次从Q中找出一个起点到该结点代价最小的结点u将u从Q中移出并放入S中对u的每一个相邻结点v进行松弛操作。松弛即对每一个相邻结点v判断源节点s到结点u 的代价与u到v的代价之和是否比原来s 到v 的代价更小若代价比原来小则要将s到v的代价更新为s到u与u到v的代价之和否则维持原样。如此一直循环直至集合Q为空即所有节点都已经查找过一遍并确定了最短路径至于一些起点到达不了的结点在算法循环后其代价仍为初始设定的值不发生变化。Dijkstra算法每次都是选择V-S中最小的路径节点来进行更新并加入S中所以该算法使用的是贪心策略。Dijkstra算法存在的问题是不支持图中带负权路径如果带有负权路径则可能会找不到一些路 径的最短路径。代码实现//最短路径——Dijkstra算法 void Dijkstra(const V src, vectorW dist, vectorint pPath) { int srci GetVertexIndex(src); int n _vertexs.size(); dist.resize(n, MAX_W); pPath.resize(n, -1); dist[srci] 0; pPath[srci] srci; //已经确定最短路径的顶点集合 vectorbool S(n,false); for (int j 0; j n; j) { //选最短路径的顶点且不在S更新其他路径 int u 0; W min MAX_W; for (int i 0; i n; i) { if (S[i] false dist[i] min) { u i; min dist[i]; } } S[u] true; //松弛更新u连接顶点v srci-u u-v 《 srci-v 更新 for (int v 0; v n; v) { if (_matrix[u][v] ! MAX_W dist[u] _matrix[u][v] dist[v]) { dist[v] dist[u] _matrix[u][v]; pPath[v] u; } } } } //打印最短路径 void PrinrtShotPath(const V src, const vectorW dist, const vectorint parentPath) { size_t N _vertexs.size(); size_t srci GetVertexIndex(src); for (size_t i 0; i N; i) { if (i srci) continue; vectorint path; int parenti i; while (parenti ! srci) { path.push_back(parenti); parenti parentPath[parenti]; } path.push_back(srci); reverse(path.begin(), path.end()); for (auto pos : path) { cout _vertexs[pos] -; } cout dist[i] endl; } }
RELATED

相关推荐

JS逆向-RSA算法加密(苏宁登录接口password2参数)

JS逆向-RSA算法加密(苏宁登录接口password2参数)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/6 7:28:38
如何用 PoB 完成一次离线 Build 规划

如何用 PoB 完成一次离线 Build 规划

如何用 PoB 完成一次离线 Build 规划 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding Path of Building(PoB)是一款面向《流放之路》玩家的离线 Bu…

📅 2026/11/6 7:28:38
Strata 本地推理引擎选型与速度实测:4 个量化版本怎么选、你的电脑能不能跑

Strata 本地推理引擎选型与速度实测:4 个量化版本怎么选、你的电脑能不能跑

Strata 本地推理引擎选型与速度实测:4 个量化版本怎么选、你的电脑能不能跑 【免费下载链接】Strata Qwen3.8-Flash-Next on any consumer hardware: one-click install for Windows / Linux. Strata inference engine, OpenAI/Anthropic API on localhost, optiona…

📅 2026/11/6 7:28:38
MORE NEWS

更多资讯

📰

ticket-purchase 零基础上手:大麦自动抢票从选城市场次到提交订单的完整链路

ticket-purchase 零基础上手:大麦自动抢票从选城市场次到提交订单的完整链路 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase ticket-pur…

📰

Folia 全屏歌词播放器怎么安装?新手一次装对,从下载到首次播放

Folia 全屏歌词播放器怎么安装?新手一次装对,从下载到首次播放 【免费下载链接】folia-major 专注于绚丽的歌词动画效果的本地音乐/navidrome/第三方多平台在线音乐播放器 A multi-platform music player for local files, Navidrome, and online stream…

📰

懂个锤子Vue VueRouter路由深入浅出

VueRouter路由深入浅出 VueRouter 介绍: Vue Router 是 Vue.js官方的路由管理器: 极大地简化了在 单页面应用程序 SPA-Single Page Application: 中构建导航和页面切换的复杂性; 单页面应用程序 SPA 单页面应用程序SPA&#…

📰

三步装完并跑通你的第一个 AI Agent:Hugging Face Agents Course 完整安装指南

三步装完并跑通你的第一个 AI Agent:Hugging Face Agents Course 完整安装指南 【免费下载链接】agents-course This repository contains the Hugging Face Agents Course. 项目地址: https://gitcode.com/GitHub_Trending/ag/agents-course Hugging Face …

📰

如何给 macOS 应用接入自动更新:Sparkle 完整集成与避坑指南

如何给 macOS 应用接入自动更新:Sparkle 完整集成与避坑指南 【免费下载链接】Sparkle A software update framework for macOS 项目地址: https://gitcode.com/gh_mirrors/sp/Sparkle Sparkle 是 macOS 平台广泛使用的开源自动更新框架:负责检查…

📰

技术写作的伦理边界与内容安全准则

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬