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

DFS算法篇:理解递归,熟悉递归,成为递归

在这里插入图片描述

1.DFS原理

那么dfs就是大家熟知的一个深度优先搜索,那么听起来很高大尚的一个名字,但是实际上dfs的本质就是一个递归,而且是一个带路径的递归,那么递归大家一定很熟悉了,大学c语言课程里面就介绍过递归,我们知道就是定义一个函数,然后自己调用自己

那么我们要理解DFS,那么其实就是要理解递归,那么要理解好掌握好递归,那么我们就得明白递归的一个过程,那么递归的一个过程无非就两个字:

”递“和”归“

那么所谓的“递”,那么我们知道要实现递归,就是定义一个函数,然后在该函数内部再调用自己,那么我们知道当执行这个函数体的内的语句的时候,一旦执行到调用该函数本身的语句时,那么我们调用该函数就会为该函数在栈上开辟一份空间,那么开辟的这个空间我们有一个专有名词也就是栈帧来称呼,那么我们会在栈帧中存放该函数体内部所定义的各种局部变量,那么每次调用一个函数我们就会为函数创建一份栈帧,那么这里我们在函数体内部调用了该函数本身,那么这种套娃的行为,程序会为我们调用的该函数又开辟一份空间,只不过这个函数就是本身,然后我们就进入到该函数内部,又重新从函数体开头执行一行一行语句,然后又执行到调用自己的函数语句,又重复我们上述的行为,那么这整个过程,从第一个函数到之后调用自己的函数的一个个过程中,这里就是一个“递”过程,那么我们可以理解第一个函数一直到调用的最后一个函数的关系我们如果用一个层级关系来描述想象的话,那么我们从第一个函数到最后一个函数就是不断往下探索深入的过程,这就是为什么我们要取名为“深度”优先搜索,这里的deep是不是就很形象的描述了递归的一个”递“过程
在这里插入图片描述

而所谓的“归”,那么我们知道我们函数在自己调用自己的时候,我们一定会设置一个终止条件,如果不设置终止条件,那函数会无限的调用自己,反复套娃,而我们刚才说了调用函数会在栈上开辟空间,如果我们反复调用,那么最终会对空间的损耗极其大,所以一旦设置好终止条件之后,也就是我们在函数体内定义的一个return语句,那么我们就会回溯,那么我们上文说了,我们从第一个函数到调用自己创建的最后一个函数的过程,我们可以用层状关系来理解,那么我们结束该调用的函数,那么也就会返回调用我们该函数的上一级函数当中去,那么同理,我们上一级函数调用结束返回也是到调用它的上一级函数当中去,所以我们就这样从底层一直会回溯到顶层的第一个函数,那么第一个函数结束就是回到调用它的main主函数当中去了,那么这就是我们的归过程.


那么在我们知道了我们递归的一个过程,那么我们在理解递归的时候,如果想不通的话就可以通过画图,然后梳理函数之间的调用关系,得到一个层级的图

那么在我们上文中,我描述“递”与“归”过程中举了一个函数自己调用自己的例子来讲解,那么该函数之间的关系就是一个层级关系,但是一旦我们将我们这个例子给修改,也就是我们在一个函数体内部调用我们函数本身的语句不只有一个,而是有多个,那么这种场景就是我们的dfs的情况了

那么此时我们要理解这种场景的话,我们就可以不能用层状关系来描述了,而得是通过树状关系来描述,没错,这个树就是我们学的数据结构的那个树,那么该函数体内有着多个函数调用语句,那么我们就以该函数作为节点,那么其下有多个分支,多个子节点,那么这个子节点就是调用的函数,那么我们执行该递归函数的过程,那么我们可以将其形象的转换为遍历这棵二叉树,假设我们在函数体内部调用该函数本身两次,那么我们执行该递归函数的过程就是从顶部到底部的一个二叉树的前序遍历,也就是先遍历左子树再遍历右子树,而如果我们在该函数体内定义了多个调用函数语句,那么该递归的函数的过程就是遍历一棵多叉树,也是先遍历左子树然后再遍历右侧的子树
那么接下来我有一个问题,读者可以自行思考一下:
那么为什么要我们该递归函数的执行流程转换成多叉树的遍历是前序遍历也就是先遍历左子树再遍历右子树而不是中序或者后序遍历呢?

那是因为我们的递归函数调用,一旦我们执行到该函数调用语句之后,我们会该调用的函数创建一份新的空间,然后就直接进入到该调用函数体的内部,而不会往下执行该调用函数之后的语句,那么也就是在二叉树中最左侧的孩子就是先被调用被创建执行的函数,而右边的函数还没有被调用,也就还没创建出它的空间,所以我们递归的执行只能是一个前序遍历的一个过程
在这里插入图片描述

那么在此模型下,也就是多叉树的遍历模型,我们在加入一个元素那就是我们的DFS了,也就是记录路径信息,那么什么是记录路径信息呢?

我们直到我们DFS的模型就是遍历一棵多叉树,那么该多叉树的第一个节点也就是根节点就是我们的第一个函数,而底部的叶子节点就是我们调用的最后一个函数,那么我们从顶部到达底部的这个路径中,我们沿途通过一个数组或者表等结构来记录我们沿途遍历的各个节点的内容,那么这就是我们的DFS,也就是我开篇所提到的带路径的递归

而不带路径的递归则是我们不记录沿途的各个节点的内容,只是接受节点往上回溯的返回值,例如斐波那契数列,那么这个不带路径的递归,就是我们的动态规划,那么动态规划也可谓是我们算法的一个重量级人物,那么我在后文会更新该内容。

那么彻底知道了我们DFS的一个原理以及模型,那么我们DFS的应用题目就是需要暴力枚举的题目,而大家经常听到的蓝桥杯的暴力方法,也就是本文的主角DFS,

那么我们接下来就看怎么用我们这DFS,那么我在下文准备了几道题目

2.应用

题目一:字符串的全部子序列 难度:EZ

题目:现在我们有一个字符串a,我们要得到该字符串的全部子序列。

例:abc的全部子序列有:"",“a”,“b”,“c”,“ab”,“ac”,“bc”,“abc”

题目思路:那么这里我们要得到该字符串的全部子序列,我们怎么得到我们一个字符串的全部子序列呢,我们就是可以通过枚举每一个位置的两种可能性,也就是该位置的字符在我们的子序列中存在还是不存在,那么我们的一个子序列的确定就是枚举每种位置的这两种可能性然后组合就可以得到我们的子序列,那么我们的枚举过程可以用一个决策树来描述,那么我们每一个位置就是该决策树的一个节点,那么该节点就有两个分支,分别对应我们该位置是否存在在子序列当中还是不存在在子序列当中,那么在每一个分支下有同理也有着两个分支,那么我们这棵决策树就是一棵完全展开的二叉树,那么我们从二叉树的顶部也就是根节点到底部的叶子节点的每一个路径就是我们一个子序列,那么我们就从根节点往下遍历,那么在遍历的过程中同时用一个变量来记录我们遍历的节点的内容,那么一旦到达底部,我们从根节点沿途记录的内容就是我们的其中一个答案

所以只要理解了DFS的一个多叉树遍历模型,那么这题的理解以及DFS的递归的实现就很轻松

代码实现:

class solution
{public:void dfs(string& a,vector<string>& ans,string temp,int i){if(i==a.size()){ans.push_back(temp);return;}dfs(a,ans,temp+a[i],i+1)//当前字符存在在子序列中dfs(a,ans,temp,i+1);//当前字符不存在在子序列当中return;}void allsubstring(string& a,vector<string>& ans){string temp;dfs(a,ans,temp,0);return;}
}

题目二:字符串的全部不重复的子序列 难度:EZ

题目:现在我们有一个字符串a,我们要求该字符串的全部且不重复的子序列

例:abcc的全部不重复子序列:"",“a”,“b”,“c”,“ab”,“ac”,“bc”,"“cc”,“abc”,“abcc”

这里的c以及abc会有重复

题目思路:那么这个题我们就得在上一个题的思路下进行一个优化,那么我们知道我们上一个题就是暴力枚举出所有的全部子序列,那么我们这个枚举的过程就是一棵二叉树,我们从顶部到底部进行遍历,而这里我们只不过在添加一个哈希表的结构,然后我们会将从顶部到底部的沿途的所有节点的记录加入到哈希表中去重即可.

代码实现:

class solution
{public:void dfs(string& a,vector<string>& ans,string temp,int i,unordered_map<string,int>& value){if(i==a.size()){if(value.find(temp)==value.end()){ans.push_back(temp);value[temp]++;}return ;}dfs(a,ans,temp+a[i],i+1)dfs(a,ans,temp,i+1);return;}void allsubstring(string& a,vector<string>& ans){string temp;unordered_map<string,int> value;dfs(a,ans,temp,0,value);return;}
}

题目三:子集 难度:MID

题目:现在有一个数组,那么数组中每个元素可以组成一个集合,请返回所有且不重复的集合。

例:[1,2,3,4]的子集有:[1],[2],[3],[4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4],[1,2,3],[1,2,4],

[1,3,4],[2,3,4],[1,2,3,4]

注意:[1,2,3]和[3,2,1]以及[2,1,3]是一个集合

题目思路:那么这里我们解决该题的一个思路还是一个枚举,那么我们按照每个位置是否在这个集合中存在来作为枚举,那么每一个位置都有两种可能,也就是存在在这个集合当中或者不存在在这个集合当中,那么这里我们就枚举每一个位置的可能性,然后每个位置的可能性所组合就是我们的子集了,那么我们枚举的过程就是一棵决策树,那么在当前每个位置的当前所做的决策就是二叉树的一个节点,那么我们现在有两种决策,要么存在在集合中要么不存在在集合中,那么在二叉树的该节点中就对应就会有两个分支,那么同理,这两个分支下有对应着两个分支,那么我们从顶部到达底部的路径的沿途的各个节点组合就是我们的子集,那么我们就遍历我们这棵二叉树,然后我们定义一个变量来记录沿途的路径上的节点内容即可。

class solution
{public:void dfs(vector<int>& a,vector<vector<int>>& ans,int index,vector<int>& current,unordered_map<string,int>& value){if(index==a.size()){for(int i=0;i<current.size();i++){a+=to_string(current[i]);}if(value.find(a)==value.end()){ans.push_back(current);value[a]++;}return;}current.push_back(a[index]);dfs(a,ans,index+1,current);current.pop_back();dfs(a,ans,index+1,current);}void all(vector<int>& a,vector<vector<int>>& ans){vector<int> current;unordered_map<string,int> value;dfs(a,ans,0,current,value);return;}
}

但是我们可以优化一下,因为我们知道这题存在重复的子集,那么所谓的重复的子集就是集合的各个值的数量一样,但是顺序不一样,那么就是重复的子集,那么我们就可以按照集合的特定的值的数量来进行一个枚举,那么首先我们可以先对数组进行一个排序,这样相同大小的数会在相邻位置,然后我们按照这样的方式来枚举,那么我们枚举集合中值为k的数在集合的数量为0的子集,然后再枚举为值为k数量为1的子集有几个,那么同理对于其他值也是这样,那么我们将每个值在当前集合的数量的可能给组合就是我们的子集,那么按照这样枚举的话我们就能够优化很多重复子集的枚举,实现剪枝

而所谓的剪枝就跟园丁修建树木的花花草草一样,我们这里的剪枝则是要修剪掉重复计算过的分支,这样减少树的遍历从而优化时间复杂度,并且也优化了空间复杂度因为减少了递归函数的调用从而不用为函数创建栈帧,而在上一个题中,我们用哈希表的方式来去重注意那个不是剪枝,我们还是会从树的顶部走到底部,然后将记录的结果加进哈希表中去重,树的分支其实并没有减少

代码实现:

class Solution {
public:void dfs(const vector<int>& nums, vector<vector<int>>& subsets, vector<int>& current, int index) {if(index==nums.size()){ans.push_back(current);return;}int i=index+1;while(i<nums.size()&&nums[i]==nums[i-1]){i++;}for(int j=0;j<i-index;j++){current.push_back(nums[index]);dfs(nums,subsets.current,i);}}vector<vector<int>> subsets(vector<int>& nums) {vector<vector<int>> result;vector<int> current;sort(nums.begin(), nums.end());  // 对数组进行排序dfs(nums, result, current, 0);return result;}
};

题目四:全排列 难度:MID

题目:那么现在有一个数组,我们要得到该数组的所有全排列

例:[1,2,3]的全排列有[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,2,1],[3,1,2]

题目思路:那么这里我们要枚举我们的所有全排列,那么这里我们的枚举思路就是我们假设我们的数组长度为n,那么意味着有n个数,那么我们分别来枚举每一个位置的数的情况,比如第一个位置有n种情况,那么第二个位置有n-1种情况,以此类推,那么我们每个位置的情况组合就得到了我们的全排列,那么我们这个枚举过程就是每一个数的决策就是该多叉树的一个节点,那么我们其中从顶部到底部的各个路径就是我们其中一个全排列,那么我们定义一个变量来记录我们从顶部到达底部的路径沿途的各个节点内容,然后该记录就是我们的一个答案

代码实现:

class solution
{public:void dfs(vector<int>& a,vector<vector<int>>& ans,vetcor<int>& temp,vector<int>& check){if(temp.size()==a.size()){ans.push_back(temp);return;}for(int i=0;i<a.size();i++){if(check[i]==0){check[i]=1;temp.push_back(a[i]);dfs(a,ans,temp,check);check[i]=0;temp.pop_back();}}}void all(vector<int>& a,vector<vector<int>>& ans){vector<int> temp;vector<int> check(a.size(),0);dfs(a,ans,temp,check);return;}
}

3.结语

那么这就是我们DFS的全部内容,那么我们DFS的应用场景就是那些需要我们去暴力枚举尝试的题目,那么每一次枚举也就是每一次所做的要做的决策就是我们树当中的节点,而其中枚举的可能性就是这个节点所对应的分支,那么我们就沿途遍历这些所有的从顶部到达底部的所有分支,并将沿途的节点内容给记录即可,那么这就是我们的DFS,本质上就是带路径的递归,那么要掌握DFS只要熟悉我们的递归,其实DFS的算法原理与思想其实很简单,挺无脑的,并且知道了DFS的算法模型就是一棵多叉树的话,那么通过递归来实现的难度就减小很多

那么最后感谢你能够耐心的看完本文,那么希望本文能够让你有所收获,我会持续更新,希望你能够多多关注,那么如果我的文章有帮组到你,那还请你多多三连支持哦,你的支持就是我创作的最大的动力!
在这里插入图片描述

相关文章:

DFS算法篇:理解递归,熟悉递归,成为递归

1.DFS原理 那么dfs就是大家熟知的一个深度优先搜索&#xff0c;那么听起来很高大尚的一个名字&#xff0c;但是实际上dfs的本质就是一个递归&#xff0c;而且是一个带路径的递归&#xff0c;那么递归大家一定很熟悉了&#xff0c;大学c语言课程里面就介绍过递归&#xff0c;我…...

让编程变成一种享受-明基RD320U显示器

引言 作为一名有着多年JAVA开发经验的从业者&#xff0c;在工作过程中&#xff0c;显示器的重要性不言而喻。它不仅是我们与代码交互的窗口&#xff0c;更是影响工作效率和体验的关键因素。在多年的编程生涯中&#xff0c;我遇到过各种各样的问题。比如&#xff0c;在进行代码…...

C语言简单练习题

文章目录 练习题一、计算n的阶乘bool类型 二、计算1!2!3!...10!三、计算数组arr中的元素个数二分法查找 四、动态打印字符Sleep()ms延时函数system("cls")清屏函数 五、模拟用户登录strcmp()函数 六、猜数字小游戏产生一个随机数randsrandRAND_MAX时间戳time() 示例 …...

基于Python的深度学习音乐推荐系统(有配套论文)

音乐推荐系统 提供实时音乐推荐功能&#xff0c;根据用户行为和偏好动态调整推荐内容 Python、Django、深度学习、卷积神经网络 、算法 数据库&#xff1a;MySQL 系统包含角色&#xff1a;管理员、用户 管理员功能&#xff1a;用户管理、系统设置、音乐管理、音乐推荐管理、系…...

Java:单例模式(Singleton Pattern)及实现方式

一、单例模式的概念 单例模式是一种创建型设计模式&#xff0c;确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例&#xff0c;是 Java 中最简单的设计模式之一。该模式常用于需要全局唯一实例的场景&#xff0c;例如日志记录器、配置管理、线程池、数据库…...

解锁养生秘籍,拥抱健康生活

在这个快节奏的时代&#xff0c;人们行色匆匆&#xff0c;常常在忙碌中忽略了健康。其实&#xff0c;养生并非遥不可及&#xff0c;它就藏在生活的细微之处&#xff0c;等待我们去发现和实践。 规律作息是健康的基础。日出而作&#xff0c;日落而息&#xff0c;顺应自然规律&am…...

数据结构之堆(Heap)

数据结构之堆&#xff08;Heap&#xff09; 数据结构之堆&#xff08;Heap&#xff09;一、堆的核心概念1. 定义与性质2. 存储方式 二、核心操作与算法1. 操作复杂度概览2. 关键操作详解(1) 向上调整&#xff08;Sift Up&#xff09;(2) 向下调整&#xff08;Sift Down&#xf…...

人工智能 - 机器学习、深度学习、强化学习是人工智能领域的理论基础和方法论

机器学习、深度学习、强化学习是人工智能领域的三大核心方向,各自具有独特的理论基础和方法论。以下是它们的核心理论知识总结: 一、机器学习(Machine Learning, ML) 1. 基础概念 目标:通过数据驱动的方式,让机器从经验中学习规律,完成预测、分类或决策任务。 核心范式…...

github上文件过大无法推送问题

GitHub 对文件大小有限制&#xff0c;超过 100 MB 的文件无法直接推送到仓库中。 解决思路&#xff1a; 使用 Git Large File Storage (Git LFS) 来管理大文件不上传对应的大文件 使用Git LFS&#xff1a; 1. 安装 Git LFS 首先&#xff0c;你需要安装 Git LFS。可以按照以…...

Elasticsearch:将 Ollama 与推理 API 结合使用

作者&#xff1a;来自 Elastic Jeffrey Rengifo Ollama API 与 OpenAI API 兼容&#xff0c;因此将 Ollama 与 Elasticsearch 集成非常容易。 在本文中&#xff0c;我们将学习如何使用 Ollama 将本地模型连接到 Elasticsearch 推理模型&#xff0c;然后使用 Playground 向文档提…...

【Linux】详谈 进程控制

目录 一、进程是什么 二、task_struct 三、查看进程 四、创建进程 4.1 fork函数的认识 4.2 2. fork函数的返回值 五、进程终止 5.1. 进程退出的场景 5.2. 进程常见的退出方法 5.2.1 从main返回 5.2.1.1 错误码 5.2.2 exit函数 5.2.3 _exit函数 5.2.4 缓冲区问题补…...

构建高效智能对话前端:基于Ant Design X 的deepseek对话应用

文章目录 实现的效果前言Ant Design X添加欢迎组件创建对话气泡存储对话历史渲染对话气泡 输入组件WebSocket 连接总结 实现的效果 待机页面&#xff1a; 等待页面&#xff1a; 完成页面&#xff1a; 前言 随着人工智能技术的飞速发展&#xff0c;大模型对话系统已成为…...

WordPress“更新失败,响应不是有效的JSON响应”问题的修复

在使用WordPress搭建网站时&#xff0c;许多人在编辑或更新文章时&#xff0c;可能会遇到一个提示框&#xff0c;显示“更新失败&#xff0c;响应不是有效的JSON响应”。这个提示信息对于不了解技术细节的用户来说&#xff0c;太难懂。其实&#xff0c;这个问题并不复杂&#x…...

华为交换机trunk简介配置

目录 一、Trunk 口简介二、Trunk 口配置案例及命令&#xff08;一&#xff09;组网需求&#xff08;二&#xff09;配置步骤&#xff08;三&#xff09;验证配置 三、注意事项 一、Trunk 口简介 Trunk 口是交换机中一种重要的端口类型&#xff0c;主要用于连接交换机与交换机、…...

DeepSeek从入门到精通(清华大学)

​ DeepSeek是一款融合自然语言处理与深度学习技术的全能型AI助手&#xff0c;具备知识问答、数据分析、编程辅助、创意生成等多项核心能力。作为多模态智能系统&#xff0c;它不仅支持文本交互&#xff0c;还可处理文件、图像、代码等多种格式输入&#xff0c;其知识库更新至2…...

【SpringBoot3】面向切面 AspectJ AOP 使用详解

文章目录 一、AspectJ介绍二、简单使用步骤 1、引入依赖2、定义一个Aspect3、开启AOP支持 三、AOP 核心概念四、切点&#xff08;Pointcut&#xff09; 1. execution2. within3. this & target4. args & args5. within & target & annotation 五、通知&#xf…...

容器运行常见数据库

一.涉及镜像压缩包 均为amd架构版本&#xff1a;mysql:5.7.42、postgres:13.16、dm8:20250206_rev257733_x86_rh6_64、oceanbase-ce:v4.0、opengauss:5.0.2 通过网盘分享的文件&#xff1a;db.tgz 链接: https://pan.baidu.com/s/1EBbFPZj1FxCA4_GxjVunWg?pwd563s 提取码: 5…...

OpenGL ES学习大纲

如果您想从头学习 OpenGL ES,以下是一个详细的学习大纲,涵盖了从基础到高级的知识点,循序渐进地帮助您掌握 OpenGL ES 的核心概念、API 使用、渲染管线、着色器编程、性能优化等内容。 1. 学习前的准备 1.1 基础知识 在学习 OpenGL ES 之前,您需要掌握以下基础知识: 数学…...

Kotlin 优雅的接口实现

1. 日常遇到的冗余的接口方法实现 日常开发中&#xff0c;经常会要实现接口&#xff0c;但是很多场景中&#xff0c;只需要用到其中一两个方法&#xff0c;例如 ActivityLifecycleCallbacks&#xff0c;它有很多个接口需要实现&#xff0c;但是很多时候我们只需要用到其中的一…...

数据结构实现顺序表的尾插,尾删,按值查找/修改/删除,按下标查找/增加/删除

头文件&#xff1a;head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAXSIZE 20enum num {success,false-1};typedef int datatype;typedef struct {int len;datatype data[MAXSIZE]; }S…...

qt实现文字跑马灯效果

实现跑马灯的方式多种多少样&#xff0c;可以通过定时器&#xff0c;或者animation等来实现。 本文通过定时器&#xff0c;将第一个文字&#xff0c;移动到最后一个这种方式来实现&#xff0c;还有其他方式哈。 直接上源码 h文件 #ifndef TEXTTICKER_H #define TEXTTICKER_…...

PyTorch Tensor 形状变化操作详解

PyTorch Tensor 形状变化操作详解 在深度学习中&#xff0c;Tensor 的形状变换是非常常见的操作。PyTorch 提供了丰富的 API 来帮助我们调整 Tensor 的形状&#xff0c;以满足模型输入、计算或数据处理的需求。本文将详细介绍 PyTorch 中常见的 Tensor 形状变换操作&#xff0…...

关于Node.js前端面试的试题概念、工作原理及实际应用

文章目录 1. 什么是Node.js&#xff1f;2. Node.js是如何工作的&#xff1f;3. Node.js与其他流行的框架相比有何优势&#xff1f;4. Node.js如何克服I/O操作阻塞的问题&#xff1f;5. 为什么Node.js是单线程的&#xff1f;6. 如果Node.js是单线程的&#xff0c;那么它是如何处…...

OpenCV机器学习(3)期望最大化(Expectation-Maximization, EM)算法cv::ml::EM

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::ml::EM 是 OpenCV 机器学习模块中的一部分&#xff0c;用于实现期望最大化&#xff08;Expectation-Maximization, EM&#xff09;算法。EM …...

Spring Boot 集成 Kettle

Kettle 简介 Kettle 最初由 Matt Casters 开发&#xff0c;是 Pentaho 数据集成平台的一部分。它提供了一个用户友好的界面和丰富的功能集&#xff0c;使用户能够轻松地设计、执行和监控 ETL 任务。Kettle 通过其强大的功能和灵活性&#xff0c;帮助企业高效地处理大规模数据集…...

Debezium同步之如何同步GIS数据

Debezium 可以用于同步数据库中的变更数据(CDC),包括GIS(地理信息系统)数据。GIS 数据通常存储在具有地理空间数据类型的表中,例如 PostGIS(PostgreSQL 的扩展)中的 geometry 或 geography 类型。通过 Debezium,可以实时捕获和同步这类数据的变更。本文章简单介绍Post…...

Java与C语言中取模运算符%的区别对比

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: Java 文章目录 &#x1f4af;前言&#x1f4af;C语言中的取模运算符 %基本行为示例 注意事项示例&#xff1a;负数取模 &#x1f4af;Java中的取模运算符 %基本行为示例 对浮点数的支持示例&#xff1a;浮点数取模 符…...

如何commit后更新.gitignore实现push

目录 步骤 1: 更新 .gitignore 文件 步骤 2: 移除已追踪的大文件 步骤 3: 提交更改 步骤 4: 尝试推送 注意事项 如果已经执行了git commit&#xff0c;但后来意识到需要更新.gitignore文件以排除某些不应该被追踪的大文件或目录&#xff0c;并希望在不丢失现有提交记录的情…...

从MySQL迁移到PostgreSQL的完整指南

1.引言 在现代数据库管理中&#xff0c;选择合适的数据库系统对业务的成功至关重要。随着企业数据量的增长和对性能要求的提高&#xff0c;许多公司开始考虑从MySQL迁移到PostgreSQL。这一迁移的主要原因包括以下几个方面&#xff1a; 1.1 性能和扩展性 PostgreSQL以其高性能…...

20250214 随笔 Nginx 负载均衡在数据库中的应用

Nginx 负载均衡在数据库中的应用 在高并发环境下&#xff0c;数据库的性能往往是系统的瓶颈。为了提高数据库的吞吐能力、优化请求分配、减少单点故障&#xff0c;我们可以使用 Nginx 负载均衡 来优化数据库的访问。本文将介绍如何使用 Nginx 进行数据库负载均衡&#xff0c;以…...

从养殖场到科技前沿:YOLOv11+OpenCV精准计数鸡蛋与鸡

前言 谁能想到,鸡蛋和鸡的计数居然能变成一项高科技活儿?想象一下,早上去市场,卖家把鸡蛋摔得稀巴烂,结果鸡蛋滚得到处都是——难道你就得一个个捡回来数?还得小心别弄错?可是,你又不是超人!别担心,科技来帮忙!今天的主角是YOLOv11和OpenCV,它们是计算机视觉领域的…...

【Qt】 Data Visualization

三维数据可视化 三维柱状图三维图的创建程序截图示例代码 三维散点图三维图创建程序截图示例代码 三维曲面图三维图创建程序截图示例代码 Data Visualization 是 Qt 中的一个三维数据可视化模块&#xff0c;可用于绘制三维柱状图、三维散点图和三维曲面。与 Charts 模块类似&am…...

python基础语法

文章目录 字面量定义分类 注释定义分类单行注释多行注释 变量定义 数据类型类型转换定义 案例 标识符定义命名规则内容限定大小写敏感不可使用关键字 命名规范变量的命名规范 运算符数学运算符赋值运算符复合赋值运算符 定义字符串定义方式 字符串拼接语法 字符串格式化语法1字…...

【C++游戏开发-五子棋】

使用C开发五子棋游戏的详细实现方案&#xff0c;涵盖核心逻辑、界面设计和AI对战功能&#xff1a; 1. 项目结构 FiveChess/ ├── include/ │ ├── Board.h // 棋盘类 │ ├── Player.h // 玩家类 │ ├── AI.h // AI类 │ └── Game.h // 游戏主逻辑 ├── src/ …...

C/C++ | 每日一练 (2)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (2)题目参考答案封装继承多态虚函数底…...

如何在 VS Code 中快速使用 Copilot 来辅助开发

在日常开发中&#xff0c;编写代码往往是最耗时的环节之一。而 GitHub Copilot&#xff0c;作为一款 AI 编码助手&#xff0c;可以帮助开发者 自动补全代码、生成代码片段&#xff0c;甚至直接编写完整的函数&#xff0c;大幅提升编码效率。那么&#xff0c;如何在 VS Code 中快…...

FFmpeg源码:av_strlcpy函数分析

一、引言 在C/C编程中经常会用到strcpy这个字符串复制函数。strcpy是C/C中的一个标准函数&#xff0c;可以把含有\0结束符的字符串复制到另一个地址空间。但是strcpy不会检查目标数组dst的大小是否足以容纳源字符串src&#xff0c;如果目标数组太小&#xff0c;将会导致缓冲区…...

【生产变更】- 集群中配置SCAN ip的不同端口应用

【生产变更】- 集群中配置SCAN ip的不同端口应用 一、概述二、操作步骤三、故障解决 一、概述 使用非默认端口&#xff08;1521&#xff09;监听scan ip。 二、操作步骤 1、添加11521端口 srvctl add listener -l lis11521 -o /opt/grid/products/11.2.0 -p 11521 srvctl st…...

RabbitMQ 3.12.2:单节点与集群部署实战指南

前言&#xff1a;在当今的分布式系统架构中&#xff0c;消息队列已经成为不可或缺的组件之一。它不仅能够实现服务之间的解耦&#xff0c;还能有效提升系统的可扩展性和可靠性。RabbitMQ 作为一款功能强大且广泛使用的开源消息中间件&#xff0c;凭借其高可用性、灵活的路由策略…...

Node.js技术原理分析系列——如何在Node.js中新增一个内置模块

本文由体验技术团队曹杨毅原创。 Node.js 是一个开源的、跨平台的JavaScript运行时环境&#xff0c;它允许开发者在服务器端运行JavaScript代码。Node.js 是基于Chrome V8引擎构建的&#xff0c;专为高性能、高并发的网络应用而设计&#xff0c;广泛应用于构建服务器端应用程序…...

从低清到4K的魔法:FlashVideo突破高分辨率视频生成计算瓶颈(港大港中文字节)

论文链接&#xff1a;https://arxiv.org/pdf/2502.05179 项目链接&#xff1a;https://github.com/FoundationVision/FlashVideo 亮点直击 提出了 FlashVideo&#xff0c;一种将视频生成解耦为两个目标的方法&#xff1a;提示匹配度和视觉质量。通过在两个阶段分别调整模型规模…...

康耐视CAM-CIC-10MR-10-GC工业相机

康耐视(COGNEX)的工业相机CAM-CIC-10MR-10-GC是CAM-CIC-10MR系列中的一款型号,主要应用于工业自动化检测和高精度视觉系统 基本参数与特性 分辨率与帧率: CAM-CIC-10MR-10-GC属于康耐视CIC系列,具备10MP(1000万像素)的分辨能力,帧率为10fps。该系列相机支持卷帘快门(R…...

解惑Python:一文解决osgeo库安装失败问题

Osgeo&#xff08;Open Source Geospatial Foundation&#xff09;是一个支持开源地理空间数据处理的基金会&#xff0c;我们可以在python中使用“osgeo”库来访问其提供的高效地理空间数据。例如&#xff0c;我们使用该模块提供的GDAL处理栅格数据&#xff0c;使用OGR处理矢量…...

3、树莓派5 安装VNC查看器 开启VNC服务器

在前序文章中&#xff08; 2、树莓派5第一次开机&#xff09;&#xff0c;可以使用三种方式开机&#xff0c;其中使用网线及wifi的方式均需要使用到VNC查看器进行远程桌面控制&#xff0c;本文将介绍如何下载安装并配置及使用VNC查看器及服务器&#xff0c;对前序文章做一些补充…...

Django 创建表时 “__str__ ”方法的使用

在 Django 模型中&#xff0c;__str__ 方法是一个 Python 特殊方法&#xff08;也称为“魔术方法”&#xff09;&#xff0c;用于定义对象的字符串表示形式。它的作用是控制当对象被转换为字符串时&#xff0c;应该返回什么样的内容。 示例&#xff1a; 我在初学ModelForm时尝…...

STM32 CAN过滤器配置和应用方法介绍

目录 概述 一、CAN过滤器核心概念 二、过滤器配置步骤&#xff08;以标准ID为例&#xff09; 三、不同模式的配置示例 四、高级配置技巧 五、调试与问题排查 六、关键计算公式 总结 概述 在STM32微控制器中&#xff0c;CAN过滤器可以配置为标识符屏蔽模式和标识符列表模…...

【第1章:深度学习概览——1.3 深度学习的核心组件与概念解析之神经网络基础】

大家好!今天咱们一头扎进深度学习的神秘领域,好好探索一下其最重要的基石 —— 神经网络。不管你是深度学习的新手小白,还是已经接触过一些基础概念,这篇文章都能助力你更透彻地理解神经网络的原理和运作机制。咱们从最基础的知识入手,一步步揭开神经网络的神秘面纱! 一、…...

Python中如何进行数据库连接?

在 Python 中进行数据库连接&#xff0c;不同的数据库需要使用不同的库。下面分别介绍几种常见数据库&#xff08;SQLite、MySQL、PostgreSQL&#xff09;的连接方法。 1. 连接 SQLite 数据库 SQLite 是一种轻量级的嵌入式数据库&#xff0c;Python 标准库中自带了sqlite3模块…...

解析 WebGPU 中 device.createBuffer 的参数意义

在 WebGPU 开发里&#xff0c;device.createBuffer 方法扮演着至关重要的角色&#xff0c;它用于创建一个 GPU 缓冲区对象&#xff0c;这个对象能够存储顶点数据、索引数据、统一数据等。下面我们就来详细剖析该方法各个参数的意义。 1. size&#xff1a;决定缓冲区容量 size …...

PLC的集成RAM,存储器卡,用户程序存储空间,数据存储容量分别指的什么,有什么关联?

1. 集成RAM 定义&#xff1a;集成RAM&#xff08;随机存取存储器&#xff09;是PLC内部的高速易失性存储器&#xff0c;用于临时存储运行时的数据&#xff08;如输入/输出状态、中间变量、计数器/定时器的当前值等&#xff09;。 特点&#xff1a; 易失性&#xff1a;断电后数…...