并查集 poj 2524,1611,1703,2236,2492,1988 练习集【蓝桥杯备赛】

目录

前言

   并查集优势

Ubiquitous Religions poj 2524

   问题描述

   问题分析

   代码

The Suspects poj 1611

   问题描述

   问题分析

   代码   

 Wireless Network poj 2236

   问题描述

   问题分析

   代码

分类

带权并查集合

   权值树构建步骤

Find them, Catch them  poj 1703

   问题描述

   问题分析

   代码

A Bug's Life poj 2492

   分析

   代码

Cube Stacking poj 1988

   分析

   代码

总结


前言

        如果想看基础在这里  并查集基础

        并查集是一种极其轻巧的高级数据结构,在算法比赛中也较为常见,所以我们借几道题来加强一下。

   并查集优势

        在开始练习之前,我们先明确并查集究竟有什么用,为什么要用并查集:

        并查集最本质的作用其实是在这个函数:

int find_set(int x) {if (x != s[x]) s[x] = find_set(s[x]);return s[x];
}

        这个路径压缩算法可以使得集合中的任何一个元素都可以在O(1)的时间复杂度下找到其所属的集合。

        根据这个优势我们就可以得出,并查集更善于解决集合类的问题

Ubiquitous Religions poj 2524

poj 2524

   问题描述

        想调查学校中学生的宗教信仰情况,但只知道两两同学之间是信仰相同宗教,问该学校中学生信仰的不同宗教的最大数量。

   问题分析

        这是一个恒明显的集合问题,具有相同宗教的同学属于一个集合,只需要将这些同学分好集合之后,统计并查集中有多少个集合即可。

        这里其他代码都是并查集的原版代码,唯一需要注意的就是如何数并查集中的集合个数,在并查集中对于每个集合只有一个x有s[x]=x;我们可以根据这个特性,计数并查集中集合的个数

int ans = 0;
for (int i = 1; i <= n; i++) {if (s[i] == i) ans++;
}
cout <<"Case "<<k<<": " << ans << endl;
k++;

   代码

#include<iostream>
using namespace std;
const int N = 320;
int s[N];void init_set() {for (int i = 1; i < N; i++) {s[i] = i;}
}int find_set(int x) {if (x != s[x]) s[x] = find_set(s[x]);return s[x];
}void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];}
}
int k = 1;
int main() {int  m, n, a, b;while (~scanf_s("%d%d", &n, &m) && (m || n)) {init_set();for (int i = 1; i <= m; i++) {cin >> a >> b;merge_set(a, b);}int ans = 0;for (int i = 1; i <= n; i++) {if (s[i] == i) ans++;}cout <<"Case "<<k<<": " << ans << endl;k++;}return 0;
}

The Suspects poj 1611

poj 1611

   问题描述

        一个学校有n名同学编号为0~n-1,m个社团,现已知编号为0的同学为感染者,如果和0号同学同属于一个社团那么也是感染者,和感染者同属于一个社团的同学也是感染者,先给出每个社团的人数以及社团同学编号,问这个学校有多少个感染者(不参加社团的同学不是感染者)。

   问题分析

        和上题一样这也是一个集合问题,和感染者同属于一个社团的同学都是感染者,我们把他们合并到一个集合中,最后在统计和编号为0同学同属于一个社团的人数。

        但是这里需要注意一个易错点,就是由于只有进行了find_set(x)的元素才会进行路径压缩,所以并不是所有的S[X]都等于他所处的集合,也有可能还未更新,此时还在中间,所以在最后需要手动进行路径压缩,其实也不会耗费太多时间,因为此时的路径压缩已经距离根节点相当近了。

        解释:

        因为在merge_set(int a,int b)函数中我们只有一开始进行了find_set(x),也就是只有一开始进行了路径压缩,之后直接将roota接到了rootb上并没有将a也接到rootb上,所以需要手动将a接到rootb上,也就是再对a进行路径压缩

void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];}
}

   代码   

#include<iostream>
using namespace std;
const int N = 10005;
int s[N];void init_set() {for (int i = 0; i < N; i++) {s[i] = i;}
}int find_set(int x) {if (x != s[x]) s[x] = find_set(s[x]);return s[x];
}void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];}
}int main() {int n, m, t, head, a;while (cin >> n >> m && (n || m)) {init_set();for (int i = 1; i <= m; i++) {cin >> t;cin >> head;for (int j = 1; j < t; j++) {cin >> a;merge_set(a, head);}}int ss = find_set(0); //找到0所在的集合int ans = 0;for (int i = 0; i < n; i++) {find_set(i);  //手动路径压缩//cout << i << " :" << s[i] <<"  "<<s[s[i]] << endl;if (s[i] == ss) ans++;}cout << ans << endl;}
}

 Wireless Network poj 2236

poj 2236

   问题描述

        有一些损坏的电脑,给出这些电脑的坐标,电脑之间距离超过某一值那么就无法接通,两相互接通的电脑之间允许通过几台电脑接通,电脑损坏也无法接通,先给出一些操作O a,代表修复编号为a的电脑,S a b代表查询a,b两台电脑是否联通

   问题分析

        这题很明显也是一个集合问题,我们可以把相互联通的电脑放在一个集合里,查询是否连通,只需要查询两台电脑是否属于一个集合即可,我们在修复电脑的操作时,需要遍历一遍所有修好的电脑,并将它们归到一个集合之中。

        还有一个问题就是如何将电脑的编号和坐标存储,以便计算两电脑距离,这里我们是由一个结构体数组node[N],其中N代表电脑编号,node存储的信息有电脑坐标以及电脑是否修好。

   代码

#include<iostream>
using namespace std;
const int N = 1005;int s[N];struct node {//暴力存点int x;int y;bool flag = false; //false代表这台计算机未被修复
}node[N];void init_set() {for (int i = 1; i < N; i++) {s[i] = i;}
}int find_set(int x) {if (x != s[x]) s[x] = find_set(s[x]);return s[x];
}void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];}
}double cal_dis(int a, int b) {double x = (node[a].x - node[b].x) * (node[a].x - node[b].x);double y = (node[a].y - node[b].y) * (node[a].y - node[b].y);// cout << y << endl;return sqrt(x + y);
}int main() {int n;double d;cin >> n >> d;init_set();for (int i = 1; i <= n; i++) {cin >> node[i].x >> node[i].y;}char c;int a, b;while (cin >> c) {if (c == 'O') {cin >> a;node[a].flag = true;//暴力遍历,每输入一个已经修好的电脑,就遍历一遍所有的电脑,判断一下是否联通for (int i = 1; i <= n; i++) {if (node[i].flag == true) {double dis = cal_dis(a, i);//如果满足距离要求说明是联通的if (dis <= d) merge_set(i,a);}}}if (c == 'S') {cin >> a >> b;int roota = find_set(a), rootb = find_set(b);if (roota == rootb) {cout << "SUCCESS" << endl;}else cout << "FAIL" << endl;}}
}

分类

        以上的题目都是并查集的第一个应用,分类,无论是第一个题目判断有几个宗教,还是第二个题目感染者,这本质上都是分类问题,而分类最难的也就是需要知道他所属于哪个集合,由于并查集可以快速找到元素所属的集合所以在合并的过程中就显得极其迅速,从而加速了分类操作速度。

带权并查集合

        怎么说呢,其实这完全是属于利用并查集可以快速找到元素所属集合的一个应用,本质上已经不是一个集合问题了,更像是利用路径压缩以及权值更新创建的一棵大部分是叶子节点(有些节点在merge_set操作之后还未路径压缩)的高效权值树。

   权值树构建步骤

        这里只讲和普通并查集不同的地方,其他都按照并查集模板来。

(1)初始化每个节点的权值,如果是距离一般会初始化为0,这需要根据实际情况选择,一般就是0或1.

        

int find_set(int x) {if (x != s[x]) {int t = s[x];  //注意这里的d[t]和下面的d[t]是不一样的,这里的d[t]还未更新s[x] = find_set(s[x]);/*if (d[x] && d[t]) {if (d[x] == d[t]) d[x] = 1;else d[x] = -1;}else d[x] = 0;*///效果和上面代码一样,纯属个人喜好d[x] = link_set(d[x], d[t], 1);}return s[x];
}

        (2) 在路径压缩过程中更新权值,因为在路径压缩过程中,在一整条路径上的节点所属的集合都合并到了根集合,那么同样的也需要更新权值。

        更新权值的方式用很多中,但本质上都是更新其与根节点的关系,这个关系可以是距离,方位,是否属于一个集合(别惊讶,上面已经说过,带权并查集本质上已经不是并查集了)。

        但其实这里的更新方式是由一定方法的,想要理解这里的更新方式,就需要了解find_set函数在运行过程中干了什么。

        这是一个递归的过程,直到找到x满足x=s[x],那么返回是s[x](为便于理解,下文假设s[x]=set),那么在回溯的过程中就会把set赋值给沿路上的每一个s[x]。

        这就是find_set的全过程,我们现在来分析要更新d[x],我们已知什么,首先未更新前的的d[x]我们是已知的,原来的d[x]代表x与进行路径压缩前的根节点的关系,这个好理解,一开始x的根节点就是自身,如果这个算法是正确的,那么随着路径压缩根节点也会更新最终得到d[x],在之后就是d[s[x]]也是已知的,这个不大好理解,但你可以想象当find_set算法开始回溯时:

  • 我们要求d[x],
  • 由于此时的d[x]=x,
  • 那么d[x]和d[s[x]]其实是相同的那么初始时这个算法是可行的
  • 此时的d[s[x]]代表的是x更新前的根节点(s[x])与整个集合根节点的关系,此时利用d[x]和d[s[x]]这两个关系,
  • 就可以成功更新d[x],把d[x]更新为x与整个集合根节点的关系,
  • 那么类推s[t]=x的话,那么d[t]已知,d[s[t]]=d[x]已知
  • 也可以把d[t]更新为t与整个集合根节点的关系
void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];/*if (d[a] && d[b]) {if (d[a] == d[b]) d[roota] = -1;else d[roota] = 1;}else d[roota] = 0;*///效果和上面代码一样,纯属个人喜好d[roota] = link_set(d[a], d[b], -1);}
}

       (3) 还有一个需要更新权值的地方就是merge_set(int a,int b,int m)操作,因为在合并操作时会将s[roota]接到s[rootb]上,此时就需要更新d[roota],多嘴一句注意的地方,这里只更新了d[roota]如果需要更新roota下的其他节点,需要额外进行路径压缩,因为此时新接到s[rootb]上的节点只有roota,这也就解释了The Suspects这题。这里我们直接上图:

  • 已知a->b关系为v,a->roota关系为m
  • 那么就可以推出b->roota的关系k
  • 已知b->roota关系k,b->rootb关系l
  • 那么就可推出roota->rootb关系h
int roota = find_set(a), rootb = find_set(b);
if (roota == rootb) {int end = link_set(d[a], d[b],1);if(end==1) cout << "In the same gang." << endl;if(end==-1) cout << "In different gangs." << endl;else cout << "Not sure yet." << endl;//效果和上面代码一样,纯属个人喜好/*if (d[a] && d[b]) {if (d[a] == d[b]) cout << "In the same gang." << endl;else cout << "In different gangs." << endl;}else cout << "Not sure yet." << endl;*/
}
//如果关系输完了根节点任然不一样,那么证明这两个集合间没有任何关系,所以无法推得a,b关系
else {cout << "Not sure yet." << endl;
}

       (4) 接下来就是如果给出a->b关系且此时roota=rootb那么就可以判断给出的a->关系是否正确:

Find them, Catch them  poj 1703

poj 1703

   问题描述

        给出一些关系和一些查询,每个查询根据已有的关系输出结果,关系的格式为 D a  b 代表a,

b这两个人不属于一个帮派。

   问题分析

        如果关系表示为a,b属于一个帮派,那么这个就是妥妥的一个并查集基础应用,这里表示的是a,b不属于一个集合,但归根结底这题还是个集合问题,那么我们优先考虑的还是并查集,因为并查集有一个特别好的优点就是可以迅速找到元素所属的集合。既然不能用并查集的分类功能,那么就考虑用并查集建立一棵权值树。

        就根据上文给出的三步逐步编写代码即可

   代码

#include<iostream>
using namespace std;const int N = 1*10e5 + 5;int s[N];
int d[N];//带权并查集 规定:
//1:代表(a,b)属于一个集合
//-1代表(a,b)不属于一个集合
//0: 代表(a,b)关系未知 void init_set() {for (int i = 1; i <= N - 1; i++) {s[i] = i;d[i] = 1;  //初始化,根节点是自己,自然是属于同一集合,初始化为1}
}int link_set(int a, int b,int c) {if (a && b) {if (a == b)  return 1*c;else return -1*c;}else return 0;
}int find_set(int x) {if (x != s[x]) {int t = s[x];s[x] = find_set(s[x]);/*if (d[x] && d[t]) {if (d[x] == d[t]) d[x] = 1;else d[x] = -1;}else d[x] = 0;*///效果和上面代码一样,纯属个人喜好d[x] = link_set(d[x], d[t], 1);}return s[x];
}void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];/*if (d[a] && d[b]) {if (d[a] == d[b]) d[roota] = -1;else d[roota] = 1;}else d[roota] = 0;*///效果和上面代码一样,纯属个人喜好d[roota] = link_set(d[a], d[b], -1);}
}int main() {int t,n,m,a, b;char c;cin >> t;while (t--) {init_set();cin >> n >> m;for (int i = 1; i <= m; i++) {cin >> c;cin >> a >> b;if (c == 'A') {int roota = find_set(a), rootb = find_set(b);if (roota == rootb) {int end = link_set(d[a], d[b],1);if(end==1) cout << "In the same gang." << endl;if(end==-1) cout << "In different gangs." << endl;else cout << "Not sure yet." << endl;//效果和上面代码一样,纯属个人喜好/*if (d[a] && d[b]) {if (d[a] == d[b]) cout << "In the same gang." << endl;else cout << "In different gangs." << endl;}else cout << "Not sure yet." << endl;*/}//如果关系输完了根节点任然不一样,那么证明这两个集合间没有任何关系,所以无法推得a,b关系else {cout << "Not sure yet." << endl;}}if (c == 'D') {merge_set(a, b); }}}
}

之后的代码就大差不差了,不多解释 

A Bug's Life poj 2492

poj 2492

   分析

   代码

#include<iostream>
using namespace std;const int N = 2005;int s[N];
int d[N];
int flag = 0;//规定:
//1:代表同性
//0:代表异性
void init_set() {for (int i = 1; i < N; i++) {s[i] = i;d[i] = 1;  //表示与i与i所属的根节点的关系}flag = 0; //顺便把flag也初始化了
}//下面这三个办法效果都一样,后两种利用了一点离散数学的知识
int cal_relation1(int a, int b) {return a == b;
}int cal_relation2(int a, int b) {return ~(a ^ b) & 1;
}int cal_relation3(int a, int b) {return !(!(a && b) && !(!a && !b));
}int find_set(int x) {if (x != s[x]) {int t = s[x];s[x] = find_set(s[x]);d[x] = cal_relation1(d[t], d[x]);}return s[x];
}void merge_set(int a, int b) {int roota = find_set(a), rootb = find_set(b);if (roota != rootb) {s[roota] = s[rootb];d[roota] = cal_relation1(cal_relation2(d[a], 0), d[b]);}else {int c = cal_relation3(d[a], d[b]);if (c == 1) {flag = 1;}}
}int main() {int t,n,m,a,b;cin >> t;for (int j = 1; j <= t; j++) {init_set();cin >> n >> m;for (int i = 1; i <= m; i++) {cin >> a >> b;merge_set(a, b);}cout << "Scenario #" << j << ":" << endl;if (flag == 1) cout << "Suspicious bugs found!" << endl;else cout << "No suspicious bugs found!" << endl;}
}

Cube Stacking poj 1988

poj 1988

   分析

        本题需要注意的是我们利用了一个cnt辅助数组存储每个集合中元素的个数

   代码

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
using namespace std;#define maxn 30005
int s[maxn], d[maxn], cnt[maxn]; //d【i】数组记录的是i节点下有几个立方体void init_set(int n)
{for (int i = 1; i <= n; i++){s[i] = i, d[i] = 0, cnt[i] = 1;}
}int find_set(int x)
{if (s[x] != x) {int t = s[x];s[x] = find_set(s[x]);d[x] += d[t];//由于路径压缩并不会改变同一个集合元素的数量,所以这里不更新cnt}return s[x];
}void merge_set(int x, int y)
{x = find_set(x), y = find_set(y);if (x != y) {s[x] = y;d[x] += cnt[y];cnt[y] += cnt[x]; //合并操作时更新}
}int main()
{int p;while (~scanf("%d", &p)){init_set(maxn - 1);while (p--){char op;scanf_s(" %c", &op);if (op == 'M'){int x, y;scanf_s("%d%d", &x, &y);merge_set(x, y);}else{int x;scanf_s("%d", &x);find_set(x);printf("%d\n", d[x]);}}}return 0;
}

总结

        并查集主要解决的就是集合问题还有权值树问题,它可以极大提高元素查询其所在集合的效率,是一个极其轻巧好用的数据结构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18200.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

zabbix监控tomcat

1. 准备JDK环境 #vim /etc/profile export JAVA_HOME/usr/local/jdk export TOMCAT_HOME/usr/local/tomcat export PATH$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOMOE/bin [rootCentOS8 ~]# source /etc/profile [rootCentOS8 ~]# java -version openjdk version &q…

Nuget For Unity插件介绍

NuGet for Unity&#xff1a;提升 Unity 开发效率的利器 NuGet 是 .NET 开发生态中不可或缺的包管理工具,你可以将其理解为Unity的Assets Store或者UPM,里面有很多库可以帮助我们提高开发效率。当你想使用一个库,恰好这个库没什么依赖(比如newtonjson),那么下载包并找到Dll直接…

如何在 Ubuntu 上安装 Mattermost 团队协作工具

简介 Mattermost 是一个开源、自托管的通信平台&#xff0c;专为团队协作设计。它类似于 Slack&#xff0c;提供聊天、消息传递和集成功能。Mattermost 在重视数据隐私的组织中特别受欢迎&#xff0c;因为它允许团队在自己的服务器上管理通信。以下是 Mattermost 的一些关键特…

初识Linux—— 基本指令(上)

前言 Linux简述 ​ Linux是一种开源、自由、类UNIX的操作系统&#xff0c;由著名的芬兰程序员林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;于1991年首次发布。Linux的内核在GNU通用公共许可证&#xff08;GPL&#xff09;下发布&#xff0c;这意味着任何人都可以自由…

VBA技术资料MF223:从文件添加新模块

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

利用RAGflow和LM Studio建立食品法规问答系统

前言 食品企业在管理标准、法规&#xff0c;特别是食品原料、特殊食品法规时&#xff0c;难以通过速查法规得到准确的结果。随着AI技术的发展&#xff0c;互联网上出现很多AI知识库的解决方案。 经过一轮测试&#xff0c;找到问题抓手、打通业务底层逻辑、对齐行业颗粒度、沉…

路径规划——RRT*算法

路径规划——RRT*算法 算法原理 RRT Star 算法是一种渐近最优的路径规划算法&#xff0c;它是 RRT 算法的优化版本。RRT Star 算法通过不断地迭代和优化&#xff0c;最终可以得到一条从起点到目标点的最优路径。 在学习RRT Star 算法之前最好先学习一下RRT原始算法&#xff1…

Java——并发工具类库线程安全问题

摘要 本文探讨了Java并发工具类库中的线程安全问题&#xff0c;特别是ThreadLocal导致的用户信息错乱异常场景。文章通过一个Spring Boot Web应用程序示例&#xff0c;展示了在Tomcat线程池环境下&#xff0c;ThreadLocal如何因线程重用而导致异常&#xff0c;并讨论了其他并发…

网络编程套接字

前言&#xff1a; 认识了网络&#xff0c;我们就应该考虑一下如何编程实现不同主机上的应用进程之间如何进行双向互通的端点。 套接字&#xff08;Socket&#xff09;是网络编程的一种基本概念&#xff0c;套接字是应用程序通过网络协议进行通信的接口&#xff0c;是操作系统提…

计算机网络:运输层 —— TCP 的拥塞控制

文章目录 TCP的拥塞控制拥塞控制的基本方法流量控制与拥塞控制的区别拥塞控制分类闭环拥塞控制算法 TCP的四种拥塞控制方法&#xff08;算法&#xff09;窗口慢开始门限慢开始算法拥塞避免算法快重传算法快恢复算法 TCP拥塞控制的流程TCP拥塞控制与网际层拥塞控制的关系 TCP的拥…

vue学习第8章(vue的购物车案例)

&#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!&#x1f64f;&#x1f64f;&#x1f64f; 文章目录…

【SpringBoot】什么是Maven,以及如何配置国内源实现自动获取jar包

前言 &#x1f31f;&#x1f31f;本期讲解关于Maven的了解和如何进行国内源的配置~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f3…

【Linux】:进程信号(详谈信号捕捉 OS 运行)

✨ 来去都是自由风&#xff0c;该相逢的人总会相逢 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;Linux—登神长阶 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞…

七、利用CSS和多媒体美化页面的习题

题目一&#xff1a; 利用CSS技术&#xff0c;结合表格和列表&#xff0c;制作并美化 “ 翡翠阁 ”页面。运行效果如下 运行效果&#xff1a; 代码 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>翡翠阁</title>&…

动态规划 —— 子数组系列-等差数列划分

1. 等差数列划分 题目链接&#xff1a; 413. 等差数列划分 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/arithmetic-slices/description/ 2. 算法原理 状态表示&#xff1a;以某一个位置为结尾或者以某一个位置为起点 dp[i]表示&#xff1a;以i位置为…

vue使用List.reduce实现统计

需要对集合的某些元素的值进行计算时&#xff0c;可以在计算属性中使用forEach方法 1.语法&#xff1a;集合.reduce ( ( 定义阶段性累加后的结果 , 定义遍历的每一项 ) > 定义每一项求和逻辑执行后的返回结果 , 定义起始值 ) 2、简单使用场景&#xff1a;例如下面…

TensorFlow 2.0 windows11 GPU 训练环境配置

前言 在一切开始之前&#xff0c;请确保你的cmd命令行和powershell命令行可以正常打开。如果不能&#xff0c;建议重装系统。我不确定这是否会影响你最终的结果&#xff0c;毕竟windows的坑太多了。 安装顺序&#xff1a;visual studio -> cuda -> cudnn -> python…

MyISAM和InnoDB介绍及切换存储引擎方法

MyISAM 和 InnoDB 都是 MySQL 数据库管理系统中常用的存储引擎&#xff08;Storage Engine&#xff09;。存储引擎决定了数据库如何存储、读取、更新数据以及如何管理事务、锁定等操作。 1. MyISAM 存储引擎 MyISAM 是 MySQL 的默认存储引擎之一&#xff0c;尤其是在早期版本…

什么是嵌入式?

目录 一、什么是嵌入式 二、嵌入式系统的特点 &#xff08;一&#xff09;专用性与隐蔽性 &#xff08;二&#xff09;高可靠性与实时性 &#xff08;三&#xff09;资源固定与小型化 三、嵌入式系统的发展历史 &#xff08;一&#xff09;20 世纪 60 年代早期雏形 &am…

在几分钟内将数据从 Oracle 迁移到 ClickHouse

ClickHouse 是一个开源的面向列的数据库管理系统。它在实时数据处理方面的出色性能显着增强了数据分析和业务洞察力。将数据从 Oracle 迁移到 ClickHouse 可以释放数据在决策中的力量&#xff0c;这是单独使用 Oracle 无法实现的。 本教程介绍如何使用 BladePipe 将数据从 Orac…