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

【C/C++算法】从浅到深学习--- 二分查找(图文兼备 + 源码详解)

绪论:冲击蓝桥杯一起加油!!
在这里插入图片描述
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”

绪论​:
本章是算法篇章的第三章二分算法,本章主要是通过题目的形式来进行学习,通过八道题让你基本了解二分法算法以及它的许多细节,在简介部分将会一定性的总结二分算法编写时的细节,通过这些了解这些细节,然后再通过前两道题了解二分算法的常见三种模板,再通过6道题巩固相信你对二分算法就会有很大的提升,后面将持续更新前缀和算法,敬请期待~
————————
早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。


二分查找算法简介

对于二分查找是什么,它的由来啥的就不过诉了,这是一个算法快速学习文章,我们通过几道题其实就能很好的理解什么事二分算法了!

特点:

  1. 最恶心、细节最多
  2. 最容易写出死循环算法
  3. 掌握后 ----》 最简单

学习的侧重点:

  1. 算法原理:数组有序的情况(不准确),应该是:发现数组有二段性规律就能使用二分
  2. 模板(不要死记硬背,理解后记忆)
    1. 朴素二分(简单但局限)
    2. 查找左边界的二分模板
    3. 查找有边界的二分模板(后面两个,较为万能,但细节很多)

注意:

  1. 从有一定单调性中的数据中,直接通过答案分析二段性(中间值,左端点,右端点)

  2. 二段性并不代表:

    1. 它不一定只是左边小右边大的
    2. 它本质是通过分析题目画出图形,查看是否能通过两个公式得出所有情况

总结(如何分析是否使用二分算法):

  1. 分析题目,画出图形
  2. 直接根据答案分析图形,看看是否能写出二段性公式
  3. 最终确定二段性,然后根据二段性情况分析使用模板一、二、三

具体训练:

1. 二分查找(非常重要的模板二分题)

题目:

在这里插入图片描述

分析题目并提出,解决方法:

  1. 暴力解法:很简单就是直接遍历一遍数组即可

但还有更加优秀的算法分析题目:
在这里插入图片描述

  • 对于暴力解法来说,他每次比较仅仅只能排除一个数
  • 但题目是有序的,却没用到,这里可以利用起来
  1. 现在随便获取一个数4 拿 target 与它进行比较
  2. 发现能一次排除多个数(如下图)
    在这里插入图片描述
  3. 取出 4 < t(target) ,那么 4 左边区间的都可以直接排除了,因为他是升序的,4 都小于target了,那么其左边的值只会更小!

这个方法,画成如下图方框内:发现其实本质通过一个数将数组划分成 “二段性”

通过一次比较将数组一下子划分成两部分:
在这里插入图片描述
二段性的本质并不只是找最中间的值,而是将数组划分成两部分的任意一点(如下图)
在这里插入图片描述
但还是得选择使用第一种最中间的点(因为这种在数学上效率是最高的)

模板一

在这里插入图片描述

二分模板主要以下步骤:

  1. 使用left、right双指针确定区间
  2. 每次从区间中获取mid最中间的值(mid = left + (right - left) / 2),然后和target值进行比较
    在这里插入图片描述
  3. 只会用下面的三种情况
    1. mid < target
    2. mid > target
    3. mid == target
    4. 当为上面三种情况时,他们的区间如何变化
    5. 很好理解 当 x < t 时:代表 mid及左边的区间都无效,那么left指针移动:left = mid + 1
    6. x > t:则类似意思:right = mid - 1(x 及 x右边区间 都无效)
    7. x == t。那就代表找到了正确区间!
      在这里插入图片描述

细节问题:

  1. 循环结束的条件
    1. left > right 才结束循环(循环条件就是 left <= left
    2. 因为left == right的值可能也需要进行判断,而判断后就会 left > right
    3. 所以不能是 left < right
  2. 求中间的值的mid 可以使用 (right - left)/ 2 + 1
  3. 时间复杂度
    在这里插入图片描述

题解核心逻辑:

该题就是最基础的二分题,直接使用上述模板即可做出:

class Solution {
public:int search(vector<int>& nums, int target) {int left = 0 ,right = nums.size() - 1;int mid,res = -1;while(left <= right){mid = ((right  - left) / 2) + left;//防止溢出if(nums[mid] < target){left = left + 1;}else if(nums[mid] > target){right = right - 1;}else{return mid;}}return -1;}
};

在这里插入图片描述

2. 在排序数组中查找元素的第一个和最后一个位置(非常重要的模板二分题)

题目:

在这里插入图片描述

分析题目并提出,解决方法:

非递减:代表要么递增,要么不变
在这里插入图片描述
暴力解法:遍历得到begin,end位置

题解核心逻辑:

分析本题要找的是一个值的区间:找左端点、右端点

拿左端点为例先直观的看出答案,然后进行分析,分析出其其实也是有二段性的
在这里插入图片描述
那么先使用二分模板一解决:
在这里插入图片描述
发现无法解决:虽然也能通过找到target的位置但还需要遍历左右两边,但这种的最大时间复杂度又变成了O(N)了

模板二:查找左端点的情况

光先看左端点来说:分析出它的二段性(如下图)
在这里插入图片描述

  1. x < t:left = mid + 1( mid + 1 因为结果一定不会在mid及其左边)
  2. x >= t:right = mid( mid 因为结果可能就是当前的值,我们不能跳过)

但其中有很多细节问题:

  1. 循环条件:使用left < right(而不是 left <= right)
    1. 当有结果的时候,若left = right还要进入的话,此时 x >= t 的那么将会执行 right = mid 的操作,这样的话就会导致right值又再一次重复的设置为了 mid,那么就将会死循环,所以说当有结果的时候是不用判断 left == right这个地方的!
      在这里插入图片描述
    2. 当数组中的值全部大于 t,那么right最终将移动到最左端和left相遇,那么其也是一样的不用进去 不然就死循环了
      在这里插入图片描述
    3. 同理 left会不断的移动到最左边,他有两种情况,一种是和right相遇(那么就和上面一样不需要进去),还有就是超过right那么就肯定出循环了 就不用考虑
      在这里插入图片描述
    4. 综合上面3种情况,已经包括了所有的可能,总结出当left = right 的时候是不要进入循环的,那么也就推道出使用 left < right
  2. 求中点mid:使用left + (right - left)/ 2(尽量不要死记)
    1. 对于找右端点来说 left每次移动 mid + 1,right 每次移动 mid
    2. 在我们求中点的操作来说是使用下述两个,但假如使用了第二种:left + (right - left + 1)就会死循环
    3. 为什么呢:因为这两个找中间值的操作本质他们的区别是在偶数时,让mid指向左边还是右边(例如 1 2 3 4 第一种方式就会找到的中点为 2,第二种方式找到的中点就会为3,具体自己算哈~)
    4. 那么回来为什么找到右边就不能用呢,是因为假如在极端情况下只剩两个数字了,left指向第一个数字,right指向第二个数组(具体如下图情况)
    5. 而此时要找的是左端点,就需要left < right 出循环,但因为right的移动是等于mid的
    6. 而此时mid求出来的却是右边和right指向的相同,还是 nums[mid] >= t,right = mid
    7. 那么就会导致right还是没有移动,再次进入循环,算mid还是一样的,right的移动还是前面的,这样就会导致死循环
    8. 这样说可能还是有点抽象,为了方便记忆:可以把 求中点方程式里面的 +1 想象成mid的位置(+1就是在右边,不+1就是在左边,通过下图右边记住mid的位置),本题是 right 移动 mid步(找左端点…),那么mid在右边的话就会和right重叠,所以不能+1;
      在这里插入图片描述

模板三:查找右端点:

和上面就几乎一致了,只不过二段性不一样,并且找中点不一样
在这里插入图片描述
对于找中点来说:因为此处的是left = mid,那么若是用 left + (right - left) / 2的话,就剩两个值时求mid就会移动到左边,和left重叠导致,死循环(和上面左边分析一致就不过诉了,若不懂可以评论细讲哈~)

最终做题,找到左右端点:

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int left = 0 , right = nums.size()-1;int mid;vector<int> res;if(nums.size() == 0) return {-1,-1};//找左端点//不要进入,不让 right可能会无限的等于midwhile(left < right){mid = left + (right - left) / 2;//内部不要+1 因为在只有两个值的时会导致 right不断的等于mid 而用于到达不了最左端if(nums[mid] < target){left = mid + 1;}else{right = mid;}}//出循环判断有结果的情况://两种移动情况出循环:// left = mid + 1: left >= right 其中left 不可能大于 right(只能left == right 循环)// 因为要打的前提是 left == right(因为只有 right(left) + 1 > right)// // right = mid 而就肯定是left == right了也不可能越界//所以综上所述 left == rightif(nums[left] == target){res.push_back(left);}else{//若不等则表示没找到return {-1,-1};}//重置left rightleft = 0;right = nums.size()-1;//查找右端点://left < right,相等可能会导致死循环 left 不断的等于 midwhile(left < right){mid = left + (right - left + 1) / 2;// +1 让mid移动到右边,防止和left重叠!!!if(nums[mid] <= target){left = mid;//等于mid是因为防止错过正确的target}else{//nums[mid] > targetright = mid - 1;//right 往右移动 -1}}//出来肯定是left == right,所以随便用,前面使用left这里使用rightif(nums[right] == target){res.push_back(right);}else{//若不等则表示没找到return {-1,-1};}return res;}
};

在这里插入图片描述
在这里插入图片描述

3. x 的平方根

题目:

在这里插入图片描述

分析题目并提出,解决方法:

分析暴力解法:从1并计算出平方,会有两种情况:

  1. 平方 小于 目标值,继续找
  2. 平方 等于 目标值,那么就找到了
  3. 平方 大于 目标值,那么表示超过了,那么就取该值前面的那个数
    在这里插入图片描述

优化,分析上图:

  1. 首先他是有序的
  2. 并且发现是有二段性的:
    在这里插入图片描述
    而此处分析题目可知:
    答案可能是:在小于区间的和刚好找到的,所以也就是找左端点的移动情况(具体如下图)
    在这里插入图片描述

题解核心逻辑:

class Solution {
public:int mySqrt(int x) {if(x < 0) return 0;//找左端点long long left = 0,right = x;int i  = 0;//使用mid中点的平方来进行快速的查找while(left < right) {long long mid = left + (right - left + 1) / 2;//因为是left 所以mid要 +1,防止重叠if((long long)mid * mid <= x){left = mid;}else{right = mid - 1;}}return left;}
};

在这里插入图片描述

4. 搜索插入位置

题目:

在这里插入图片描述

分析题目并提出,解决方法:

本题是一个非常明显的二分:有序 + 查找值(只不过是查找目标位置)
分析本题:需要找到是插入的位置,分析示例:
在这里插入图片描述
直接看出插入的位置,分析他插入的位置:是大于等于的区间,所以也就是找右端点
在这里插入图片描述

题解核心逻辑:

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0,right = nums.size() -1;while(left < right){int mid = left + (right - left) / 2;//这里是找right,所以不+1if(nums[mid] < target){left = mid + 1;}else right = mid;}if(nums[left] < target)return left + 1;//处理示例三,但需要放到最后时return left;}
};

在这里插入图片描述

5. 山脉数组的峰顶索引

题目:

在这里插入图片描述

分析题目并提出,解决方法:

分析题目:不难想出暴力解法,遍历数组找到第一个 arr[i] > arr[i+1]的值即可
在这里插入图片描述
但分析下其中本质也是有二段性的:在峰顶左边:arr[i] >= arr[i-1],峰顶右边:arr[i] < arr[i-1](具体如下图)
在这里插入图片描述

题解核心逻辑:

通过上面的分析出了二段性:
其中再次强调二段性本质是通过某个式子将数组分组两块,而这个式子就是left、right的移动方法,其中包含答案的区域移动就是mid步!
而本题答案是在左端点的所以left = mid(这题右端点也能使用,不过左端点更符合思考逻辑)

class Solution {
public:int peakIndexInMountainArray(vector<int>& arr) {int left = 0,right = arr.size()-1;if(arr.size() == 1) return 0;while(left < right){int mid = left + (right - left + 1) / 2;if(arr[mid] >= arr[mid-1]){left = mid;}else{//arr[mid] < mid - 1right = mid - 1;}}return left;}
};//右端点解法:
class Solution {
public:int peakIndexInMountainArray(vector<int>& arr) {int left = 0,right = arr.size()-1;while(left < right){int mid = left + (right - left) / 2;if(arr[mid] >= arr[mid+1]){right = mid;}else{//arr[mid] < mid - 1left = mid + 1;}   }return left;}
};

在这里插入图片描述

6. 寻找峰值

题目:

在这里插入图片描述

分析题目并提出,解决方法:

分析题目:不难想出其暴力解法的三种情况:
在这里插入图片描述
分析题目:
其实也对于某个点 i 来说,它的左右相邻的数无非两种情况:

  1. arr[i] > arr[i + 1]:此时峰值在 i 的左区间一定会出现,所以再次查找左区间就够了,如果要找左区间对于 right= mid(i) 即可(mid已经指向了左区间)
  2. arr[i] < arr[i+1]:此时峰值在 i 的右区间一定会出现,所以查找右区间就够了,查找右区间:因为 i 位置肯定不是所以 left = mid + 1
  3. 最终当left 和 right 相遇则找到了结果
    在这里插入图片描述
    将上图二段性再分析下得二分中指针移动情况:
    在这里插入图片描述
    本题也能很好的说明:二分查找并不一定只是在有序的地方使用的,本题就是一个无序的数列
    本题和上一题本质非常像,只不过分析不一样,但我们一定要注意分析的过程,通过简单的例子直接看出答案进行分析,得出二段性(能区间划分成两块的式子)

题解核心逻辑:

class Solution {
public:int findPeakElement(vector<int>& nums) {int left = 0,right = nums.size()-1;while(left < right){int mid = left + (right - left) / 2;if(nums[mid] >= nums[mid + 1]){right = mid;}else{left = mid + 1;}}return left;}
};

在这里插入图片描述

7. 寻找旋转排序数组中的最小值

题目:

在这里插入图片描述

分析题目并提出,解决方法:

其中暴力解法很简单:简单遍历计数器记录得出结果(但本题要去logn的时间复杂度那么很明显可能就是二分)
在这里插入图片描述
分析题目画出如下折线图(明显的二段性):
在这里插入图片描述
既然是二段性不妨好好的看一下图形,分析出其中的如何通过式子得出二段性
分析可知其中可以使用D点,进行和mid的值进行比较,就会只有两种可能(具体如下图)

  1. 当mid指向A ~ B区间的时候, mid的值一定大于D点的值
  2. 当mid指向C~D区间的时候,mid值是小于等于D点的值的

题解核心逻辑:

最终通过二段性也得出二分的公式:
在这里插入图片描述

class Solution {
public:int findMin(vector<int>& nums) {int left = 0,right = nums.size() - 1;int d = nums[right];while(left < right){int mid  = left + (right - left) / 2;//不用 + 1 right = midif(nums[mid] > d){left = mid + 1;}else{right = mid;}}return nums[right];}
};

在这里插入图片描述
此处不直接拿A点是因为假如它没有选择那么就是一个递增的,就会出现一定的问题!
在这里插入图片描述
但也能做出来只需要将这种情况给排除即可:

class Solution {
public:int findMin(vector<int>& nums) {int left = 0,right = nums.size() - 1;int a = nums[0];if(a < nums[right]){//判断第一个点和最后一个点,若小则代表没有旋转过return a;}while(left < right){int mid  = left + (right - left) / 2;//不用 + 1 right = midif(nums[mid] >= a){//在A~B区间left = mid + 1;}else{right = mid;}}return nums[right];}
};

8. 点名特别奇怪的二段性!

题目:

在这里插入图片描述

分析题目并提出,解决方法:

分析题目不难想出下面4种解法:
在这里插入图片描述

题解核心逻辑:

而本题仍然可以二段性:
这个二段性比较奇怪,我们借助数组小标来查看它的二段性,发现:

  1. 前半段下标和数字一致
  2. 后半段下标比数字小1(具体如下图)
    在这里插入图片描述
    那么就推出二分公式:
    在这里插入图片描述

其中注意一个边界情况:
在这里插入图片描述
当缺失的是最后的值,那么需要出循环后,因为他是不断的向右移动的,最终会到达最后然后出循环,此时判断最后一个值它的下标是否符合,若相等则表示缺少是最后的值(也就是上图的4),反之若不相等则表示正常出循环

class Solution {
public:int takeAttendance(vector<int>& records) {int left = 0,right = records.size()-1;while(left < right){int mid = left + (right - left) / 2;if(records[mid] == mid){left = mid + 1;//在左区间}else right = mid;}//如果right 到达最后 再次判断是否和下标相等,若相等则表示是 最后值的 下一个 缺少了if(records[right] == right) return right + 1;return right;}
};

在这里插入图片描述

相关文章:

【C/C++算法】从浅到深学习--- 二分查找(图文兼备 + 源码详解)

绪论&#xff1a;冲击蓝桥杯一起加油&#xff01;&#xff01; 每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是算法篇章的第三章二分算法&#xff0c;本章主要是通过题目的形式来进行学习&…...

HTML之JavaScript使用JSON

HTML之JavaScript使用JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON是JavaScript对象的字符串表示法&#xff0c;它使用文本表示一个js对象的信息&#xff0c;可以将json字符串转换…...

elementui:element中el-dialog点击关闭按钮清除里面的内容和验证

问&#xff1a; element中el-dialog点击关闭按钮清除里面的内容和验证 回答&#xff1a; 在el-form中设置:before-close取消的回调函数就可以了...

从零搭建微服务项目(第5章——SpringBoot项目LogBack日志配置+Feign使用)

前言&#xff1a; 本章主要在原有项目上添加了日志配置&#xff0c;对SpringBoot默认的logback的配置进行了自定义修改&#xff0c;并详细阐述了xml文件配置要点&#xff08;只对日志配置感兴趣的小伙伴可选择直接跳到第三节&#xff09;&#xff0c;并使用Feign代替原有RestT…...

传输层协议TCP (上)

文章目录 前言TCP报文格式TCP连接管理连接建立与中止三次握手三次握手的状态变化为什么是三次握手 四次挥手四次挥手的状态变化FIN_WAIT_2 状态可能导致连接长时间不释放的问题TIME_WAIT状态作用 复位报文段非法连接请求其他异常情况 半打开连接同时握手同时关闭 参考资料 前言…...

Proxmox 更新软件包数据库(TASK ERROR: command ‘apt-get update‘ failed: exit code 100)

1、连接自己报错的物理机Shell&#xff0c;编辑文件 vi /etc/apt/sources.list.d/pve-enterprise.list 2、注释文件的第一行在开头加上# 按I进入编辑模式后 开头添加# 然后shift&#xff1a; 输入wq或者wq&#xff01;进行保存 3、注释后执行两个命令apt-get update 和 apt…...

java程序员进阶之路需要的学习过程

http://blog.csdn.net/qq_37267015/article/details/77108692...

C#01项目——计算器

实现需求: 可以连续相加&#xff0c;并记录计算表达式。 实现逻辑 1、利用字符串加减原则&#xff0c;获取相加的数值。 2、将数值存入到列表中&#xff0c;需要计算最终结果时&#xff0c;遍历列表中数值&#xff0c;全部相加 数字键 判断计算式长度是否超出上限根据运算…...

windows蓝牙驱动开发-在蓝牙配置文件驱动程序中接受 L2CAP 连接

L2CAP 服务器配置文件驱动程序会响应来自远程设备的传入逻辑链接控制和适应协议 (L2CAP) 连接请求。 例如&#xff0c;PDA 的 L2CAP 服务器配置文件驱动程序将响应来自 PDA 的传入连接请求。 接收传入 L2CAP 连接请求 1. 若要接收来自特定 PSM 的任何远程设备的传入 L2CAP 连…...

如何下载AndroidStudio的依赖的 jar,arr文件到本地

一、通过jitpack.io 下载依赖库 若需要下载 com.github.xxxxx:yy-zzz:0.0.2 的 jar则 https://jitpack.io/com/github/xxxxx/yy-zzz/0.0.2/ 下会列出如下build.logyy-zzz-0.0.2.jaryy-zzz-0.0.2.pomyy-zzz-0.0.2.pom.md5yy-zzz-0.0.2.pom.sha1jar 的下载路径为https://jitpack…...

QT笔记——QRadioButton

文章目录 1、概要2、实际的应用2.1、创建多个QRadioButton,只可同时选中其中一个&#xff0c;点击后实现对应的槽函数 1、概要 实现QRadioButton相关的应用&#xff1b;2、实际的应用 2.1、创建多个QRadioButton,只可同时选中其中一个&#xff0c;点击后实现对应的槽函数 创建…...

Vue 2 + Vite 项目集成 ESLint 和 Prettier

在 Vue 2 Vite 项目中集成 ESLint 和 Prettier 可以帮助你规范代码风格并自动格式化代码。以下是详细的步骤&#xff1a; 1. 安装 ESLint 和 Prettier 相关依赖 在项目根目录下运行以下命令&#xff0c;安装 ESLint、Prettier 和相关插件&#xff1a; npm install --save-de…...

uniapp canvas 生成海报并保存到相册

前言&#xff1a; 之前写过一篇canvas小程序画图只要是canvas各种方法的实际应用&#xff0c;有兴趣的小伙伴也可以看看 微信小程序&#xff1a;使用canvas 生成图片 并分享_小程序canvas生成图片-CSDN博客 上一篇文章是小试牛刀&#xff0c;这次是更加全面的记录生成海报的…...

无人机不等同轴旋翼架构设计应用探究

“结果显示&#xff0c;对于不等组合&#xff0c;用户应将较小的螺旋桨置于上游以提高能效&#xff0c;但若追求最大推力&#xff0c;则两个相等的螺旋桨更为理想。” 在近期的研究《不等同轴旋翼性能特性探究》中&#xff0c;Max Miles和Stephen D. Prior博士深入探讨了不同螺…...

C语言中隐式类型转换 截断和整型提升

C的整形算数总是至少以缺省整形类型的精度来进行的 为了获得这个精度 表达式中的字符和短整形操作数在使用之前被转换为普通整形 这种类型转换成为整型提升 给出代码实例↓ #include<stdio.h> int main() {//char signed charchar a 3;char b 127;char c a b;pri…...

R语言学习计划启动

R语言入门课 生信基地已然落地&#xff0c;我们希望能够给大家提供系统性、形成性、规范性的生信教学。前面几次活动中同学们表示希望能够有线下集中学习以及针对性的指导、答疑。所以&#xff0c;此次我们计划于2025年02月22日~23日(周六周日)推出"生信R语言入门课"…...

AI写代码工具时代:前端开发技能迭代的挑战与应对

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术飞速发展&#xff0c;深刻地改变着各个行业&#xff0c;前端开发领域也不例外。AI技术不仅带来了新的开发模式&#xff0c;也显著加快了前端开发技能的迭代速度&#xff0c;给前端工程师带来了巨大的挑战。本文将深入…...

消息队列之-springcloud-mq-stream 学习

背景: 开发中我们往往需要用到mq中间件进行消息处理,但是市面上的mq中间件实在太多了,导致我们在集成过程中困难重重,尤其在微服务当中,比如我们有一个订单模块、物流模块 他们都用到了mq,订单用的是rabbitmq 物流用的是kafka 导致当我们需要向这两个模块推送mq消息时,需…...

数据结构(考研)

线性表 顺序表 顺序表的静态分配 //线性表的元素类型为 ElemType//顺序表的静态分配 #define MaxSize10 typedef int ElemType; typedef struct{ElemType data[MaxSize];int length; }SqList;顺序表的动态分配 //顺序表的动态分配 #define InitSize 10 typedef struct{El…...

【16届蓝桥杯寒假刷题营】第1期DAY4

5.倍数区间 - 蓝桥云课 5. 倍数区间 问题描述 给定一个长度为 n 的数组 a&#xff0c;定义 f(i) 表示包含 ai​ 的最长区间长度&#xff0c;要求该区间中的所有数都是 ai​ 的倍数。请计算不同的 f(i) 的个数&#xff0c;其中 1≤i≤n。 输入格式 第一行包含一个正整数 n …...

「软件设计模式」适配器模式(Adapter)

软件设计模式深度解析&#xff1a;适配器模式&#xff08;Adapter&#xff09;&#xff08;C实现&#xff09; 一、模式概述 适配器模式&#xff08;Adapter Pattern&#xff09;是结构型设计模式中的"接口转换器"&#xff0c;它像现实世界中的电源适配器一样&#…...

进阶版MATLAB 3D柱状图

%% 1. 数据准备 % 假设数据是一个任意形式的矩阵 % 例如&#xff1a;5行 x 7列的矩阵 data [3 5 2 6 8 4 7;7 2 6 9 3 5 8;4 8 3 7 2 6 9;6 1 5 8 4 7 2;9 4 7 3 6 2 5];% 定义行和列的标签&#xff08;可选&#xff09; rowLabels {Row1, Row2, Row3, Row4, Row5}; % 行标签…...

【Elasticsearch】token filter分词过滤器

以下是Elasticsearch中常见的分词过滤器&#xff08;Token Filter&#xff09;的详细说明&#xff0c;基于搜索结果中的信息整理&#xff1a; 1.Apostrophe • 功能&#xff1a;处理文本中的撇号&#xff08;apostrophe&#xff09;&#xff0c;例如将“OReilly”转换为“ore…...

一天急速通关SpringMVC

一天急速通关SpringMVC 0 文章介绍1 介绍1.1 MVC架构与三层架构1.2 Spring MVC介绍1.3 入门程序 2 请求的映射3 请求数据的接收3.1 RequestParam接收3.2 POJO/JavaBean接收3.3 RequestHeader和CookieValue接收 4 请求数据的传递5 视图5.1 视图的理解5.2 请求转发和响应重定向的…...

MongoDB 7 分片副本集升级方案详解(下)

#作者&#xff1a;任少近 文章目录 1.4 分片升级1.5 升级shard11.6 升级shard2,shard31.7 升级mongos1.8重新启用负载均衡器1.9 推荐MongoDB Compass来验证数据 2 注意事项&#xff1a; 1.4 分片升级 使用“滚动”升级从 MongoDB 7.0 升级到 8.0&#xff0c;即在其他成员可用…...

如何在 MySQL 5.6 中实现按季度分组并找到销量最高的书籍

如何在 MySQL 5.6 中实现按季度分组并找到销量最高的书籍 引言问题描述实现步骤1. 计算每本书在每个季度的累计销量2. 找到每个季度的最高累计销量3. 匹配最高销量的书籍 总结扩展练习 引言 在数据分析和业务报表中&#xff0c;经常需要对数据进行分组统计&#xff0c;并找到每…...

JAVA生产环境(IDEA)排查死锁

使用 IntelliJ IDEA 排查死锁 IntelliJ IDEA 提供了强大的工具来帮助开发者排查死锁问题。以下是具体的排查步骤&#xff1a; 1. 编写并运行代码 首先&#xff0c;我们编写一个可能导致死锁的示例代码&#xff1a; public class DeadlockExample {private static final Obj…...

群体智能优化:粒子群算法(PSO)详解与实战

一、引言&#xff1a;从鸟群行为到优化算法 1995年&#xff0c;社会心理学家James Kennedy和电气工程师Russell Eberhart通过观察鸟群觅食行为&#xff0c;提出了著名的粒子群优化算法&#xff08;Particle Swarm Optimization, PSO&#xff09;。这一算法仅用不到30年时间&am…...

k8s集群搭建参考(by lqw)

文章目录 声明配置yum源安装docker安装 kubeadm&#xff0c;kubelet 和 kubectl部署主节点其他节点加入集群安装网络插件 声明 由于看了几个k8s的教程&#xff0c;都存在各种问题&#xff0c;自己搭建的时候&#xff0c;踩了不少坑&#xff0c;最后还是靠百度csdnchatGPT才搭建…...

vue3+vite项目引入electron运行为桌面项目

一、安装electron npm install --save-dev electron二、项目根目录添加electron文件 在此文件夹中添加两个js文件&#xff1a;main.js、preload.js main.js: // Modules to control application life and create native browser window const { app, BrowserWindow } requ…...

教育小程序+AI出题:如何通过自然语言处理技术提升题目质量

随着教育科技的飞速发展&#xff0c;教育小程序已经成为学生与教师之间互动的重要平台之一。与此同时&#xff0c;人工智能&#xff08;AI&#xff09;和自然语言处理&#xff08;NLP&#xff09;技术的应用正在不断推动教育内容的智能化。特别是在AI出题系统中&#xff0c;如何…...

使用 Flask 构建流式返回服务

使用 Flask 构建流式返回服务是一个很常见的应用场景&#xff0c;特别是在需要逐步传输大数据或进行长时间操作的场景下&#xff08;比如下载大文件、实时日志等&#xff09;。Flask 中可以通过 Response 对象来实现流式响应。以下是一个简单的例子&#xff0c;展示了如何在 Fl…...

Redis 集群相关知识介绍

Redis 集群详解&#xff1a;从入门到实战 Redis 是一个高性能的开源数据库&#xff0c;支持多种数据结构&#xff0c;广泛应用于缓存、消息队列、实时分析等领域。随着业务规模的增长&#xff0c;单机 Redis 的性能和容量往往无法满足需求&#xff0c;因此 Redis 集群&#xf…...

宏基传奇swift edge偶尔开机BIOS重置

电脑是acer swift edge&#xff0c; SFA16-41&#xff0c;出厂是Win11系统&#xff0c; BIOS版本出厂1.04&#xff0c;更新到了目前最新1.10。 问题是 会偶尔开机ACER图标变小跑到屏幕左上方&#xff0c;下次开机BIOS就会被重置&#xff0c;开机等待很长时间。 因为是偶尔现象的…...

DeepSeek是如何通过“蒸馏”技术打造自己的AI模型

1 引言&#xff1a; 最近&#xff0c;外媒对中国公司——DeepSeek进行了猛烈抨击&#xff0c;指控其采用了所谓的“蒸馏”&#xff08;Distillation&#xff09;技术&#xff0c;涉嫌抄袭甚至作弊。那么&#xff0c;什么是“蒸馏”技术&#xff1f; 在人工智能领域&#xff0c;…...

你如何利用SIMD(如SSE/AVX)优化图像处理的性能?

SIMD优化问题 1. SIMD 在图像处理中的优化方式2. 典型应用场景3. SIMD 的常见优化技巧4. 总结 利用 SIMD&#xff08;Single Instruction, Multiple Data&#xff09; 指令集&#xff08;如 SSE/AVX/AVX2/AVX-512&#xff09;优化图像处理的性能&#xff0c;可以极大地提升计算…...

支付宝 IoT 设备入门宝典(上)设备管理篇

相信不少朋友最近都被支付宝“碰一下”广告刷屏&#xff0c;“不用打开 APP 支付就碰一下”几个字一出简直自带BGM……其实“碰一下”就是支付宝 IoT 设备的一种&#xff0c;趁着热度还在&#xff0c;我会分为设备管理和设备经营上下两篇&#xff0c;简单介绍一下支付宝 IoT&am…...

Go语言 Web框架Gin

Go语言 Web框架Gin 参考 https://docs.fengfengzhidao.com https://www.liwenzhou.com/posts/Go/gin/#c-0-7-2 返回各种值 返回字符串 package mainimport ("net/http""github.com/gin-gonic/gin")func main() {router : gin.Default()router.GET("…...

蓝桥杯-洛谷刷题-day5(C++)(为未完成)

1.P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布 i.题目 ii.代码 #include <iostream> #include <string> using namespace std;int N, Na, Nb; //0-"剪刀", 1-"石头", 2-"布", 3-"蜥", 4-"斯"&#xff1…...

【Unity3D优化】使用ASTC压缩格式优化内存

在Unity3D手游开发中&#xff0c;合理选择纹理压缩格式对于优化内存占用、提高渲染效率至关重要。本文将记录近期在项目内进行的图片压缩格式优化过程&#xff0c;重点介绍从ETC2到ASTC 5x5的优化方案及其带来的收益。 1. 现状分析&#xff1a;从ETC2到ASTC 6x6 block 在项目…...

NO.13十六届蓝桥杯备战|条件操作符|三目操作符|逻辑操作符|!||||(C++)

条件操作符 条件操作符介绍 条件操作符也叫三⽬操作符&#xff0c;需要接受三个操作数的&#xff0c;形式如下&#xff1a; exp1 ? exp2 : exp3条件操作符的计算逻辑是&#xff1a;如果 exp1 为真&#xff0c; exp2 计算&#xff0c; exp2 计算的结果是整个表达式的结果&am…...

【uniapp-小程序】实现方法调用的全局tips弹窗

【uniapp-小程序】实现方法调用的全局tips弹窗 开发背景弹窗组件全局调用封装配置项入参全局注入使用 附带&#xff1a;如何在uniapp-H5项目中实现全局自定义弹窗组件定义定义vue插件引入 笑死&#xff0c;只有在想找工作的时候才会想更新博客。 开发背景 本来是个uniapp开发…...

springboot如何将lib和jar分离

遇到一个问题&#xff0c;就是每次maven package或者maven install后target中的jar很大&#xff0c;少的50几MB&#xff0c;大的100多兆 优化前&#xff1a; 优化后&#xff1a; 优化前 优化后压缩率77.2MB4.65MB93% 具体方案&#xff1a; pom.xml中 <build><…...

深入探索C语言中的字符串处理函数:strstr与strtok

在C语言的字符串处理领域&#xff0c; strstr 和 strtok 是两个非常重要的函数&#xff0c;它们各自承担着独特的功能&#xff0c;为开发者处理字符串提供了强大的支持。 一、strstr函数&#xff1a;字符串查找的利器 strstr 函数用于在一个字符串中查找另一个字符串的首次出现…...

Django学习笔记(第一天:Django基本知识简介与启动)

博主毕业已经工作一年多了&#xff0c;最基本的测试工作已经完全掌握。一方面为了解决当前公司没有自动化测试平台的痛点&#xff0c;另一方面为了向更高级的测试架构师转型&#xff0c;于是重温Django的知识&#xff0c;用于后期搭建测试自动化平台。 为什么不选择Java&#x…...

npm版本号标记

在 npm 中,版本号的标记遵循 语义化版本控制(Semantic Versioning, SemVer) 的规则,版本号通常由 主版本号(major)、次版本号(minor) 和 修订版本号(patch) 组成,格式为: <major>.<minor>.<patch>1. 版本号格式 主版本号(major):当你做了不兼…...

无人机雨季应急救灾技术详解

无人机在雨季应急救灾中发挥着至关重要的作用&#xff0c;其凭借机动灵活、反应迅速、高效安全等特点&#xff0c;为救灾工作提供了强有力的技术支撑。以下是对无人机雨季应急救灾技术的详细解析&#xff1a; 一、无人机在雨季应急救灾中的应用场景 1. 灾情侦查与监测 无人机…...

算法与数据结构(多数元素)

题目 思路 方法一&#xff1a;哈希表 因为要求出现次数最多的元素&#xff0c;所以我们可以使用哈希映射存储每个元素及其出现的次数。每次记录出现的次数若比最大次数大&#xff0c;则替换。 方法二&#xff1a;摩尔算法 摩尔的核心算法就是对抗&#xff0c;因为存在次数多…...

详解如何使用Pytest内置Fixture tmp_path 管理临时文件

关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理&#xff0c;构建成功的基石 在自动化测试工作之前&#xff0c;你应该知道的10条建议 在自动化测试中&#xff0c;重要的不是工具 临时目录在测试中起着至关重要的作用&#xff0c;它为执行和验证代码提供了一个可控…...

量子计算的五大优势

量子计算的优势有哪些&#xff1f; 量子计算是一个快速发展的领域&#xff0c;有望彻底改变我们处理复杂计算问题的方式。那么&#xff0c;量子计算的优势是什么&#xff1f;与经典计算相比&#xff0c;量子计算又有哪些优势呢&#xff1f;当我们探索量子力学的世界以及量子系…...