【优选算法 | 滑动窗口】滑动窗口算法:高效处理子数组和子串问题
算法 | 相关知识点 | 可以通过点击 | 以下链接进行学习 | 一起加油! |
---|---|---|---|---|
双指针 |
在本篇文章中,我们将深入剖析滑动窗口算法的核心原理。从基础概念到实战应用,带你了解如何利用滑动窗口高效解决连续子数组和子串等问题。无论你是算法入门的新手,还是希望提升代码效率的高手,滑动窗口都将成为你优化算法的重要武器!
🌈个人主页:是店小二呀
🌈C/C++专栏:C语言\ C++
🌈初/高阶数据结构专栏: 初阶数据结构\ 高阶数据结构
🌈Linux专栏: Linux
🌈算法专栏:算法
🌈Mysql专栏:Mysql
🌈你可知:无人扶我青云志 我自踏雪至山巅
文章目录
- 209.长度最小的子数组
- 3.无重复字符的最长子串
- 1004.最大连续1的个数 |||
- 1658.将 x 减到0的最小操作数
- 904.水果成篮
- 438. 找到字符串中所有字母异位词
- 30. 串联所有单词的子串
- 76.最小覆盖子串
209.长度最小的子数组
【题目】:209.长度最小的子数组
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组
【算法思路】
首先,我们需要明确,子数组和子字符串都指的是数组中一段连续的部分,而子序列则不具有连续性。
1.解法一:暴力枚举
通过两层循环枚举所有可能的情况,再通过一层循环求和进行判断,初步的时间复杂度为O(N^3)。
【优化方案】
1.为了优化,可以引入一个变量 sum
来记录当前的和,从而将时间复杂度优化到O(N^2)。
2.在暴力解法的思路大致明确后,不要急于编写代码。可以先通过模拟过程发现规律,然后逐步进行优化。
第一个优化点:利用加法的性质,加入一个正数总是会增大结果。题目要求的是最小的序列,当sum >= target
时,right
继续向右移动没有意义,这部分属于无效枚举。
第二个优化点:每当统计出满足条件的子序列后,left++
后,right
不需要回到left
位置。根据加法性质,减少范围时,总和必然会减少,因此无需回到left
,这可以进一步优化算法。
2.解法二:同向双指针
同向双指针实际上就是滑动窗口,通过两个指针维护一个区间的数值,类似一个窗口。当我们利用单调性时,可以有效地使用滑动窗口技术。
从[判断 -> 更新结果 -> 出窗口 -> 判断]
,形成一个闭环,因此需要使用循环语句。同时,更新结果的位置是根据题目需求确定的,并非判断完后立刻更新。
【代码实现】
class Solution
{
public:int minSubArrayLen(int target, vector<int>& nums){int n =nums.size();int len =INT_MAX;int sum = 0;//进窗口for(int left = 0, right =0; right < n; right++){//插入数据sum += nums[right];//判断while(sum >= target ){//更新len = min(len, right - left + 1);sum -= nums[left++];}}return len == INT_MAX ? 0 : len;}
};
【个人思考】
到 sum >= target
。没有必要继续right++,而是改变left位置不断进行判断,这里在双指针算法篇章有所说明,用于规避没有必要的枚举行为。
滑动窗口的正确性:利用单调性,规避了很多没有必要的枚举行为。
虽然代码使用两层循环,但是时间复杂度优化为O(N),时间复杂度主要是看思想。这里就left和right滑动。N + N = 2N ~ N
.
3.无重复字符的最长子串
【题目】:3.无重复字符的最长子串
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
【算法思路】
首先流程还是配合示例分析题目,尝试得到暴力解法的逻辑(这里一般为暴力枚举),模拟实现过程,得到规律,在此规律上进行优化,得知采用某一种算法
1.解法一:暴力枚举配合哈希表
暴力枚举和哈希表的时间复杂度:O(N²)
我们根据题目需求模拟实现流程,取一部分区间进行观察(pww)。从p出发向右枚举可能的情况,直到遇到pw时结束,然后将起点右移,而不是继续枚举。由于我们从全知视角进行观察,继续枚举pww不符合题目要求,因此选择停止。为了判断字符是否重复出现,我们使用哈希表。
2.解法二:滑动窗口
比起如何实现逻辑,更重要的是如何知道为什么需要使用滑动窗口思想,不然就是巧妇难为无米之炊。
从图中可以看到,right
指向元素a,导致哈希表中下标为a的元素值为2,出现了重复情况。此时需要移动left
指针,重新计算子串长度,但left
应该移动到哪里呢?
很明显,right
停下是因为遇到了重复字符。如果没有重复字符,right
就可以继续向右移动。因此,left
需要跳过重复字符,之后right
才能继续向右扩展,重新计算长度。
问题在于,left
应该跳到什么位置?由于right
停下是因为遇到重复字符,left
应该跳过重复字符,否则无论left
移动到哪里,在[left, right]
区间内,right
都不会再前进,因为该区间内仍然有重复字符。完成这一步后,right
不需要回到left
位置,继续向右移动即可。
判断条件就是hash是否出现重复字符,如果出现重复需要不断移除字符次数和移动left位置,直到left达到重复字符的下一个位置。
【代码实现】
class Solution
{public:int lengthOfLongestSubstring(string s) {int hash[128]={0};int n = s.length();int ret = 0;for(int left = 0, right = 0; right < n; right++){hash[s[right]]++;while(hash[s[right]] > 1)hash[s[left++]]--;ret = max(ret, right - left + 1);}return ret;}
};
1004.最大连续1的个数 |||
【题目】: 1004. 最大连续1的个数 III
输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。
【算法思路】
首先,通过示例分析题目的含义。简单来说,这道题目要求找到最长的子数组,通常我们会使用滑动窗口的方法。但为了更好地理解,我们可以先从暴力解法入手,通过模拟实现过程发现其中的规律,然后再对其进行优化,形成更高效的算法思路。
通过分析,'最多翻转k个零’的意思是对于数值为零的部分,我们最多可以翻转[0, k]个零,而目标是将所有零都翻转成一的状态。同时,我们需要返回连续1的最大个数,即找到最长的连续1子数组。从红色部分可以看到,当零的个数超过k时,翻转就会停止。这道题与上一道题非常相似,因此我们可以引入一个变量count
来统计当前子数组中零的个数,以便满足题目的要求。
1.解法一:暴力枚举 + zero计数器
如果使用暴力枚举法来处理所有情况,针对每个零进行翻转操作,最后还需要再将其翻转回去,这种做法既繁琐又容易出错。此时,我们应该思考,既然翻转不能超过k个零,是否真的需要执行复杂的翻转操作呢?
可以将问题转化为:寻找一个最长的子数组,其中零的个数不超过k个。
2.解法二:滑动窗口
当我们得到了暴力解法的逻辑,现在需要模拟实现发现规律,进行优化。
首先,当right
指针停下时,left
需要移动到下一个1
的位置,这样right
就无法继续移动了。这种情况的发生是由于count > 2
,因此需要调整left
指针的位置,直到count <= 2
为止。通过这种方式,能够确保right
继续向前推进,同时维护零的个数不超过2。
其次,当left
移动到合适的位置后,right
不需要重新回到left
的位置重新移动,因为[left, right]
已经是一个合法的区间。
【代码实现】
class Solution {public:int longestOnes(vector<int>& nums, int k) {int n = nums.size();int count = 0;int len = 0;for(int left = 0, right = 0; right < n; right++){if(nums[right] == 0) count++;while(count > k){if(nums[left++] == 0) count--;}len = max(len, right - left + 1);}return len;}
};
1658.将 x 减到0的最小操作数
【题目】:1658. 将 x 减到 0 的最小操作数
输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0
【算法思路】
【难点分析】
在这个问题中,我们很难直接控制需要移除的数组nums
最左边或最右边的元素数量。
为了解决这个问题,可以通过两个指针来控制左右两边的情况。例如,我们可以固定左边的数据,让右边的数据向右移动,并且逐步减去相应的数字。根据不同的情况进行处理,但不同的情况非常多,操作复杂且效率不高。
【正难则反】
考虑到题目提示中提到最小操作数与长度有关,可以尝试使用滑动窗口的思想。
实际上,我们可以将问题转化为:找出一个最长的子数组,其元素和正好等于 sum
跟第一道题是类似的,我就不细说了,主要注意的是最后是求最小长度,需要数组总长度 - 中间部分最长的长度。
【代码实现】
class Solution {public:int minOperations(vector<int>& nums, int x){int len = nums.size();int sum = 0;for(int a : nums) sum += a;int target = sum - x; int ret = -1;if(target < 0) return -1;for(int left = 0, right = 0, tmp = 0; right < len; right++){tmp += nums[right];//进窗口while(tmp > target){tmp -= nums[left++];}if(target == tmp) ret = max(ret, right - left + 1);}if(ret == -1) return ret;else return len - ret;}
904.水果成篮
【题目】:904. 水果成篮
输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。
【算法思路】
这道题目较长,读完后可以总结为:找出一个最长的子数组,且该子数组中不超过两种类型的水果。题目要求返回可以收集的水果的最大数量。一般情况下,可以考虑使用滑动窗口算法来解决,但并非所有情况都适用,因此仍然需要通过暴力解法来找到最优的解决方案。
1.解法一:暴力枚举 + 哈希表
根据题目要求,当遇到不同类型的水果需要停下来,但是我们这里是通过肉眼很容易观察到,对此我们需要一个哈希表hash<int, int>
来统计次数和类型。
2.解法二:滑动窗口
在暴力枚举过程中,left
不断向右移动来更新起点,等待枚举操作,而right
则从left
的位置开始向右移动。但当right
停下时,原因是水果种类超过了2种。这时,right
如果重新回到left
位置,水果种类不会变得更多,因此不需要再回到left
位置。
当水果种类超过2时,left
需要向右移动,同时哈希表也需要同步更新,删除该水果的出现次数。当某种水果的出现次数为零时,应该从哈希表中删除该水果种类(这需要判断该水果的出现次数是否为零,才能决定是否删除)。问题的关键在于如何处理这种水果种类,并且它在循环中的作用是什么。
在这里,我们不使用hash
容器,因为数据范围是有限的。通过使用一个定长数组来代替哈希表,可以提高效率。
【代码实现】
class Solution {public:int totalFruit(vector<int>& f){int n = f.size();int hash[100001] = {0};int len = 0, kinds = 0;for(int left = 0, right = 0; right < n; right++){if(hash[f[right]] == 0) kinds++;hash[f[right]]++;while(kinds > 2){hash[f[left]]--;if(hash[f[left]] == 0) kinds--;left++;}len = max(len, right - left + 1);}if(kinds == 1) return n;else return len;}
};
438. 找到字符串中所有字母异位词
【题目】:438. 找到字符串中所有字母异位词
解法一:暴力解法 + 哈希表
由题意可得,字母顺序不影响结果,那么可以将两边字符排序,再通过双指针遍历判断下两个字符串是否相等,但是这样子时间复杂度:O(nlogn + n)。
既然不考虑顺序,而在乎出现次数,可以借助哈希表辅助。
【题目】:
解法二:滑动窗口 + 哈希表
由于字符串 p
的异位词长度与 p
相同,我们可以利用滑动窗口来优化判断过程。在字符串 s
中,我们维护一个长度与 p
相同的滑动窗口,并在滑动过程中追踪窗口中每个字符的出现频率。
具体步骤如下:
- 使用两个长度为 26 的数组来模拟哈希表:一个记录窗口中字符的频率,另一个记录字符串
p
中字符的频率。 - 每当窗口滑动时,更新这两个数组:移除窗口前一个字符,加入新的字符。
- 如果两个数组中的字符频率相同,则说明当前窗口中的子串是字符串
p
的异位词。
【Cheek 机制优化】
在使用滑动窗口判断异位词时,通过指针遍历哈希表进行比较,每次最多比较 26 次(因为只有 26 个字母)。
但为了进一步优化,我们可以引入一个 count
变量,专门用来统计窗口中“有效字符”的数量。当窗口中的字符频率与目标字符串 p
的频率完全一致时,count
会反映出当前窗口是一个异位词。
- 【进窗口】:
if(++hash2[in - 'a'] <= hash1[in - 'a']) count++;
- 【出窗口】:
if(hash2[out - 'a']-- <= hash1[out - 'a']) count--;
class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> ret;int hash1[26] = {0};for(auto ch : p) hash1[ch - 'a']++;int hash2[26] = {0};int m = p.length();int count = 0;for(int left = 0, right = 0; right < s.length(); right++){char in = s[right];if(++hash2[in - 'a'] <= hash1[in - 'a']) count++;if(right - left + 1 > m){char out = s[left++];if(hash2[out - 'a']-- <= hash1[out - 'a']) count--;}if(m == count) ret.push_back(left);} return ret;}
};
30. 串联所有单词的子串
【题目】:30. 串联所有单词的子串
输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。
【算法思路】
1.解法一:暴力解法 + 哈希表
如果将每个单词看作由字母构成的字符串,那么问题就变成了「找到字符串中所有字母的异位词」。实际上,这与之前处理字符的异位词问题类似,只是这次我们处理的对象是单词而不是单个字符。
2.解法二:滑动窗口 + 哈希表
【细节问题】
通过图示划分,从不同单词位置为起点,会划分长度同为len的不同组合。所以我需要外嵌for循环为滑动窗口的次数,次数取决于单词长度。
移动的步长是单词的长度,其中我们以count变量统计"有效字符串"的长度,这里同样需要借助哈希表。其中在实际使用哈希表时,我们并不需要过多担心哈希碰撞或哈希算法的内部实现,因为它们是由库的实现提供的,已经经过优化和测试。
在模拟过程中,right
指针会移动 len
的位置,因此我们需要判断条件为 right + len <= s.size()
,以确保窗口不会超出字符串 s
的边界
【代码实现】
class Solution {
public:vector<int> findSubstring(string s, vector<string>& words){vector<int> v;unordered_map<string,int> hash1;for(auto& str : words) hash1[str]++;int len = words[0].size(),m = words.size();//进行len次滑动窗口for(int i = 0; i < len; i++){unordered_map<string,int> hash2;for(int left = i, right = i,count = 0; right + len <= s.size(); right += len){//进窗口string in = s.substr(right,len);hash2[in]++;if(hash1[in] && hash2[in] <= hash1[in]) count++;if(right - left + 1 > len * m){//出窗口string out = s.substr(left,len);if(hash1[out] && hash2[out]-- <= hash1[out]) count--;left += len;}if(count == m) v.push_back(left);}}return v;}
};
【语法优化】:如果s不存在p中单词,直接短路。
76.最小覆盖子串
【题目】:76. 最小覆盖子串
【算法思路】
1.解法一:暴力枚举 + 哈希表
通过暴力解法绘制抽象图可以分析出,right
不需要重新遍历,因为区间 [left, right]
和 [left + 1, right]
之间存储的信息是相同的。只需移动 left
,然后判断两个情况:是否符合需求,如果符合需求则继续,否则调整。由此可以推导出我们需要使用滑动窗口优化算法
2.解法二:滑动窗口 + 哈希表
【优化:判断条件】
这道题的算法思路与前面几道题相似,但优化哈希表遍历核对的判断条件有所不同。之前通过 count变量统计有效元素的次数,而这里不再单纯比较次数,而是比较元素的种类。
优化方式:使用 count
变量标记有效字符的种类,只有当所有种类的字符次数相等时,才认为满足条件并进行统计
【优化:数组模拟容器】
由于题目中字符全为小写字母,若使用容器,可能会带来较大的时间开销。因此,推荐使用数组来模拟哈希表,这样可以大幅提高效率。
【问题】:大于进行统计会导致重复
【代码实现】
class Solution {
public:string minWindow(string s, string t) {int hash1[128] = {0};int kind = 0;for(auto&ch : t) {if(hash1[ch]++ == 0) kind++;} int hash2[128] = {0};int count = 0;// 种类int len = INT_MAX;int begin = -1;for(int left = 0, right = 0; right < s.size(); right++){char in = s[right];hash2[in]++;if(hash2[in] == hash1[in]) count++;while(count == kind){//更新结果if(right - left + 1 < len){len = right - left +1;begin = left;}char out = s[left++];if(hash2[out] == hash1[out]) count--;hash2[out]--;}}if(begin == -1) return "";else return s.substr(begin,len);}
};
快和小二一起踏上精彩的算法之旅!关注我,我们将一起破解算法奥秘,探索更多实用且有趣的知识,开启属于你的编程冒险!
相关文章:
【优选算法 | 滑动窗口】滑动窗口算法:高效处理子数组和子串问题
算法相关知识点可以通过点击以下链接进行学习一起加油!双指针 在本篇文章中,我们将深入剖析滑动窗口算法的核心原理。从基础概念到实战应用,带你了解如何利用滑动窗口高效解决连续子数组和子串等问题。无论你是算法入门的新手,还是…...
RabbitMQ全栈实践手册:从零搭建消息中间件到SpringAMQP高阶玩法
目录 前言 认识MQ 同步调用 异步调用 技术选型 安装 SpringAMQP 交换机类型 队列交换机绑定 环境搭建 Fanout交换机 声明队列和交换机 消息发送 消息接收 总结 Direct交换机 声明队列和交换机 消息发送 消息接收 总结 Topic交换机 声明队列和交换机 消息…...
头歌实训之存储过程、函数与触发器
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
系统架构设计中的DSSA方法:理论、实践与行业深度应用
引言 在软件架构设计领域,DSSA(Domain-Specific Software Architecture,领域特定软件架构)是一种专注于垂直行业或业务领域的架构设计方法论。与通用架构设计不同,DSSA通过提炼领域共性需求、构建可复用资产库&am…...
设计心得——数据结构的意义
一、数据结构 在老一些的程序员中,可能都听说过,程序其实就是数据结构算法这种说法。它是由尼克劳斯维特在其著作《算法数据结构程序》中提出的,然后在一段时期内这种说法非常流行。这里不谈论其是否正确,只是通过这种提法&#…...
【C】初阶数据结构12 -- 冒泡排序
本篇文章主要讲解经典排序算法 -- 冒泡排序。 目录 1 算法思想 2 代码 3 时间复杂度与空间复杂度分析 1) 时间复杂度 2) 空间复杂度 1 算法思想 选择排序是一种经典的交换排序算法。其算法思想也比较简单,主要是比较相邻元素&…...
HTTP, AMQP, MQTT之间的区别和联系是什么?华为云如何适配?
目录 🔗 一、共同点(联系): 🔍 二、区别对比: 📘 三、简要说明 1. HTTP 2. AMQP 3. MQTT 🔗 四、三者联系(在华为云IoT平台中的应用) 🎯 …...
WPF之项目创建
文章目录 引言先决条件创建 WPF 项目步骤理解项目结构XAML 与 C# 代码隐藏第一个 "Hello, WPF!" 示例构建和运行应用程序总结相关学习资源 引言 Windows Presentation Foundation (WPF) 是 Microsoft 用于构建具有丰富用户界面的 Windows 桌面应用程序的现代框架。它…...
CrewAI Community Version(二)——Agent
目录 1. Agent总览2. Agent属性3. 创建Agent3.1 YAML配置3.2 直接用代码定义3.3 运行结果 参考 1. Agent总览 在CrewAI框架中,Agent是一个能具备下列能力的自主单元: 1. 执行特定的任务 2. 基于它的角色和目标进行决策 3. 使用工具完成任务 …...
阿里云VS AWS中国区:ICP备案全攻略与常见误区解析
导语 在中国大陆开展互联网服务时,ICP备案是必不可少的合规步骤。然而,随着云服务的多样化,许多企业在选择备案路径时常常感到困惑。本文将深入解析阿里云和AWS中国区的备案区别,为您提供清晰的操作指南,助您避开备案陷阱,确保业务合规运营。 一、备案基本原则 1. 服务器决定…...
基于libdxfrw库读取样条曲线并离散为点
在计算机辅助设计(CAD)与制造(CAM)领域,DXF(Drawing Exchange Format)格式文件被广泛用于存储与交换矢量图形信息。样条曲线作为DXF文件中常见的复杂曲线类型,其准确读取与离散化处理…...
学习 Apache Kafka
学习 Apache Kafka 是一个很好的选择,尤其是在实时数据流处理和大数据领域。以下是一个系统化的学习建议,帮助你从入门到进阶掌握 Kafka: 1. 先决条件 在开始 Kafka 之前,确保你具备以下基础: Java 基础:K…...
5.3/Q1,GBD数据库最新文章解读
文章题目:The burden and trend prediction of ischemic heart disease associated with lead exposure: Insights from the Global Burden of Disease study 2021 DOI:10.1186/s12940-025-01155-w 中文标题:与铅暴露相关的缺血性心脏病的负担…...
java智慧城管综合管理系统源码,前端框架:vue+element;后端框架:springboot;移动端:uniapp开发,技术前沿,可扩展性强
智慧城管综合执法系统采用B/S模式设计与手机等移动终端架构,采用 java编程语言前端框架:vueelement;后端框架:springboot;数据库:mysql5.7;移动端:uniapp技术开发设计。具有使用与维…...
【锂电池剩余寿命预测】GRU门控循环单元锂电池剩余寿命预测(Matlab完整源码)
目录 效果一览程序获取程序内容代码分享研究内容GRU门控循环单元在锂电池剩余寿命预测中的应用摘要关键词1. 引言1.1 研究背景1.2 研究现状与问题1.3 研究目的与意义2. 文献综述2.1 锂电池剩余寿命预测传统方法2.2 深度学习在锂电池寿命预测中的应用2.3 研究空白与本文切入点3.…...
开发首个Spring Boot应用
📋 前置条件 🎯 在开始之前,请打开终端并运行以下命令以确保已安装正确版本的 Java: $ java -version openjdk version "17.0.4.1" 2022-08-12 LTS OpenJDK Runtime Environment (build 17.0.4.11-LTS) OpenJDK 64-Bi…...
2025第十六届蓝桥杯大赛(软件赛)网络安全赛 Writeup
2025第十六届蓝桥杯大赛(软件赛)网络安全赛 Writeup 2025第十六届蓝桥杯大赛(软件赛)网络安全赛 Writeup情报收集黑客密室逃脱 数据分析ezEvtxflowzip 密码破解EnigmaECBTraineasy_AES 逆向分析ShadowPhases 漏洞挖掘分析RuneBrea…...
HTTP 协议深度解析:从基础到实战的完整指南
HTTP(HyperText Transfer Protocol)是 应用层协议,用于客户端(浏览器、APP)与服务器之间的数据交互。以下从协议原理、核心机制到实际案例全面解析,涵盖 HTTP/1.1 到 HTTP/3 的演进。 一、HTTP 核心特性 …...
5G助力智慧城市的崛起——从概念到落地的技术实践
5G助力智慧城市的崛起——从概念到落地的技术实践 引言:智慧城市中的“隐形脉络” 随着城市化的快速推进,传统的城市管理方式已经难以满足人口增长和资源优化的需求。智慧城市的概念应运而生,通过技术创新实现智能化、可持续发展的城市生态…...
4.25test
R7-5 小黄与研究生会(20) 分数 12 全屏浏览 切换布局 作者 王秀 单位 福州大学 福州大学研究生院怡山的同学们为了在国家对抗新冠疫情期间献出自己的一份力量,他们决定为奋战在一线的医护人员送去了演出。小黄作为研究生协会的会长,他让每位男同学均带去了若干只猫或狗…...
Unity-Shader详解-其一
今天我们来介绍Unity的一大核心组件:shader。 Shader Shader就是我们的着色器,用于控制图形的渲染的计算和生成。 对于不同的引擎,具体实现渲染的方法也不一样,也就是我们俗称的不同的图形引擎API,比如OpenGL,Direct…...
WPF与C++ 动态库交互
WPF与C++动态库交互技术详解 一、基本交互方式概述 WPF应用程序与C++动态库交互主要有以下几种方式: P/Invoke调用(平台调用)COM互操作C++/CLI桥接层内存映射文件命名管道/Socket通信本文将重点介绍最常用的P/Invoke和C++/CLI两种…...
自动化测试实战篇
文章目录 目录1. 自动化实施步骤1.1 编写web测试用例1.2 自动化测试脚本开发1.3 测试报告 目录 自动化实施步骤 1. 自动化实施步骤 1.1 编写web测试用例 注: 因为这里仅作为演示,所以设计的用例并不是非常完整 1.2 自动化测试脚本开发 # common/Util…...
基于pandoc的MarkDown格式与word相互转换小工具开发(pyqt5)
这里写目录标题 开发目标准备工作源代码程序打包其他事项命令行使用pandoc关于pandoc默认表格无边框的说明 开发目标 采用word格式模板,实现高级定制样式。具备配置保存功能,方便快捷。自定义转换选项、pandoc路径。 准备工作 开发环境:Wi…...
JVM知识点(一)---内存管理
一、JVM概念 什么是JVM? 定义: Java Virtual Machine - java程序的运行环境(java二进制字节码的运行环境) 好处: 一次编写,到处运行自动内存管理,垃圾回收功能数组下标越界越界检查多态 比较jvm jre jdk区别 学习路…...
Apache NetBeans 25 发布
Apache NetBeans 25 已于 2025 年 2 月 20 日发布3。NetBeans 是一个主要面向 Java 的集成开发环境,同时支持 C/C、PHP、JavaScript 和其他编程语言1。以下是一些主要的更新内容: Gradle 的优化与增强:优化单文件测试功能,即使测试…...
【设计模式区别】装饰器模式和适配器模式区别
装饰器模式(Decorator Pattern)和适配器模式(Adapter Pattern)都是 结构型设计模式 或者说 包装模式 (Wrapper),用于解决对象的组合和扩展问题,但它们的核心目的、结构和使用场景有显…...
矫平机终极指南:特殊材料处理、工艺链协同与全球供应链管理
一、特殊材料矫平:挑战与创新解决方案 1. 高温合金(如Inconel 718)处理 技术难点: 屈服强度高达1100 MPa,传统矫平力不足 高温下易氧化,需惰性气体保护环境 解决方案: 采用双伺服电机驱动&a…...
stm32进入睡眠模式的几个注意点
(1)关闭systick (2)先关闭外设时钟,再屏蔽中断,避免先屏蔽中断再关闭外设时钟导致中断挂起无法进入睡眠模式(立即被唤醒)。 参考: 注:图片截自《RM0433参考手…...
深入理解网络安全中的加密技术
1 引言 在当今数字化的世界中,网络安全已经成为个人隐私保护、企业数据安全乃至国家安全的重要组成部分。随着网络攻击的复杂性和频率不断增加,保护敏感信息不被未授权访问变得尤为关键。加密技术作为保障信息安全的核心手段,通过将信息转换为…...
学习设计模式《六》——抽象工厂方法模式
一、基础概念 抽象工厂模式的本质是【选择产品簇(系列)的实现】; 抽象工厂模式定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类; 抽象工厂模式功能:抽象工厂的功能是为一系列相关对象或相互依…...
MySQL 数据类型
文章目录 数据类型数据类型分类数据类型tinyint类型(整型)总结bit类型(字节) 浮点类型float类型decimal类型 字符串类型char类型varchar(变长字符串) char 和 varchar的对比日期类型enum和set类型ÿ…...
基于Tcp协议的应用层协议定制
前言:本文默认读者已掌握 TCP 协议相关网络接口知识,将聚焦于应用层协议的设计与剖析,有关底层通信机制及业务逻辑部分仅作简要概述,不再展开详述。 目录 服务器 一、通信 二、协议 1.序列化与反序列化 2. 封包与解包 三、业…...
Flink反压问题解析
一、什么是反压(Backpressure)? 反压(Backpressure) 是流处理系统中的一种流量控制机制。当下游算子处理速度低于上游数据生产速度时,系统会向上游传递压力信号,迫使上游降低数据发送速率,避免数据堆积和系统崩溃。 Flink 通过动态反压机制实现这一过程,但其副作用是…...
C语言中结构体的字节对齐的应用
一、字节对齐的基本原理 计算机的内存访问通常以固定大小的块(如 4 字节、8 字节)为单位。若数据的内存地址是块大小的整数倍,称为 自然对齐。例如: int(4 字节)的地址应为 4 的倍数。 double(…...
大规模数据同步后数据总条数对不上的系统性解决方案:从字段映射到全链路一致性保障
一、引言 在数据同步(如系统重构、分库分表、多源整合)场景中,“本地数据一致,生产环境条数对不上”是典型痛点。问题常源于并发处理失控、数据库性能瓶颈、字段映射错误、缓存脏数据等多维度缺陷。本文结合实战经验,…...
美团Java后端二面面经!
场景题是面试的大头,建议好好准备 Q. [美团]如何设计一个外卖订单的并发扣减库存系统? Q.[美团]为啥初始标记和重新标记需要STW? Q.[美团]骑手位置实时更新,如何保证高并发写入? Q.[美团]订单表数据量过大导致查询…...
35-疫苗预约管理系统(微服务)
技术: RuoYi框架 后端: SpringBootMySQLspringCloudnacosRedis 前端: vue3 环境: Idea mysql maven jdk1.8 用户端功能 1.首页:展示疫苗接种须知标语、快速预约模块 2.疫苗列表:展示可接种的疫苗 3.预约接种: 用户可进行疫苗预约接种 修改预约时间 …...
Ext JS模拟后端数据之SimManager
Ext.ux.ajax.SimManager 是 Ext JS 框架中用于拦截 Ajax 请求并返回模拟数据的核心工具,适用于前后端分离开发、原型验证或独立测试场景。它通过配置灵活的规则和模拟处理器(Simlet),帮助开发者在不依赖真实后端的情况下完成前端功能开发。 simlets 是simulated servers的…...
BT169-ASEMI无人机专用功率器件BT169
编辑:ll BT169-ASEMI无人机专用功率器件BT169 型号:BT169 品牌:ASEMI 封装:SOT-23 批号:最新 引脚数量:3 特性:单向可控硅 工作温度:-40℃~150℃ BT169单向可控硅ÿ…...
4月26日星期六今日早报简报微语报早读
4月26日星期六,农历三月廿九,早报#微语早读。 1、广州多条BRT相关线路将停运,全市BRT客运量较高峰时大幅下降; 2、国务院批复:同意在海南全岛等15地设立跨境电商综合试验区; 3、我国首次实现地月距离尺度…...
如何将 sNp 文件导入并绘制到 AEDT (HFSS)
导入 sNp 文件 打开您的项目,右键单击 “Result” 绘制结果 导入后,用户可以选择它进行打印。请参阅下面的示例。要点:确保从 Solution 中选择它。...
Shell脚本-for循环应用案例
在Shell脚本编程中,for循环是一种强大的工具,用于处理重复性任务。无论是批量处理文件、遍历目录内容还是简单的计数任务,for循环都能提供简洁而有效的解决方案。本文将通过几个实际的应用案例来展示如何使用for循环解决具体的编程问题。 案…...
MATLAB基础应用精讲-【基础知识篇】发布和共享 MATLAB 代码
目录 MATLAB发布代码---生成文档pdf 分节符对发布文件的分节 实时脚本 Matlab workspace与m脚本数据共享 发布和共享 MATLAB 代码 在实时编辑器中创建和共享实时脚本 发布 MATLAB 代码文件 (.m) 添加帮助和创建文档 发布 MATLAB 代码文件 (.m) 可创建包括您的代码、注释…...
Shell脚本-while循环语法结构
在Shell脚本编程中,while循环是一种重要的流程控制语句,它允许我们重复执行一段代码,直到指定的条件不再满足为止。与for循环不同,while循环通常用于条件驱动的迭代,而不是基于列表或范围的迭代。本文将详细介绍Shell脚…...
Java基础第四章、面向对象
一、成员变量 示例: 二、JVM内存模型 类变量就是静态变量 三、构造方法 默认构造方法、定义的构造方法(不含参数、含参数) 构造方法重载: this关键字 this关键字应用:对构造方法进行复用,必须放在第一行 四、面向对象的三大特征 1…...
【基础IO上】复习C语言文件接口 | 学习系统文件接口 | 认识文件描述符 | Linux系统下,一切皆文件 | 重定向原理
1.关于文件的预备知识 1.1 文件的宏观理解 广义上理解,键盘、显示器等都是文件,因为我们说过“Linux下,一切皆文件”,当然我们现在对于这句话的理解是片面的;狭义上理解,文件在磁盘上,磁盘是一…...
linux离线部署open-metadata
OpenMetadata 环境及离线资源关闭防火墙禁止防火墙关闭 SELinux 创建用户安装JDK安装mysql安装Elasticsearch安装open-metadata 环境及离线资源 系统:CentOS Linux release 7.9.2009 (Core) JDK:17 Mysql: 8.0 OpenMetadata:1.6.…...
Exposure Adjusted Incidence Rate (EAIR) 暴露调整发病率:精准量化疾病风险
1. 核心概念 1.1 传统发病率的局限性 1.1.1 公式与定义 传统发病率公式为新发病例数除以总人口数乘以观察时间。例如在某社区观察1年,有10例新发病例,总人口1000人,发病率即为10/10001=0.01。 此公式假设所有个体暴露时间和风险相同,但实际中个体差异大,如部分人暴露时间…...
信令与流程分析
WebRTC是h5支持的重要特征之一,有了它,不再需要借助音视频相关的客户端,直接通过浏览器的Web页面就可以实现音视频聊天功能。 WebRTC项目是开源的,我们可以借助WebRTC,构建自己的音视频聊缇娜功能。无论是前端JS的Web…...