物流网站给做软件/2022年最火的关键词
滑动窗口
在上一篇文章中,我们了解到了双指针算法,在双指针算法中我们知道了前后指针法,这篇文章就要提到前后指针法的一个经典的使用 —— 滑动窗口,在前后指针法中,我们知道一个指针在前,一个指针在后,但是两个指针都是向前移动,如果两个指针之间的元素或者下标之间的差值有一些别的作用或者含义的时候(本质上就是子数组或者子串),我们会使用到滑动窗口这个算法思想,下面以第一道例题为引例。
题目实战
引例 —— 长度最小的子数组
https://leetcode.cn/problems/minimum-size-subarray-sum/
这道题目要求我们找到最少元素构成的子数组之间所有的数据总和大于等于 target , 也就是找子数组的题目,如果使用暴力美学,那么就需要枚举出所有的子数组,然后进行比较,时间复杂度为 O(N ^ 2)
暴力美学也是使用的是前后指针法,但是由于没有利用好递增关系,所以你也可以认为滑动窗口也是前后指针法的进阶,我们先这样看,使用一个指针遍历数组,然后使用 count 来统计遍历过的元素之和,由于数组的元素是正整数,所以 count 会随着 指针的移动而增加,在数学上,我们认为这是一种递增关系。
这样我们可以先让一个指针遍历数组(这个可以叫进窗口),直到 count >= target 的时候,就需要更新最短的长度,以及让 后指针 向前移动(这个可以叫出窗口),直到 count < target,此时这个循环会让count 减小,这也就让长度减小,所以要在循环中也顺便更新最短的长度。这就是滑动窗口的思路
思考为什么前指针不需要后退,而是直接向前遍历即可?
在暴力美学中,前指针都是回到后指针前一个位置,然后开始继续向前遍历计算新的 count,但是由于具有递增关系,前指针回退是没有必要的,因为已经计算好当前的 count 了,你的回退反而浪费原本的count 这个数值。只需要继续向前遍历即可,我们这个 count 在滑动窗口是动态变化的,根据前指针移动而增加,根据后指针移动而减少。
所以滑动窗口是对前后指针法的暴力美学的优化
在思考问题的时候,我们优先会想到暴力美学,因为它直观也容易想到,如果符合滑动窗口的特性,我们就可以尝试优化。
总结一下滑动窗口的算法思想:
1.进窗口
2.出窗口
3.更新答案(下面是说成数据)(根据题意调整具体位置)
时间复杂度为O(2N) = O(N)
class Solution {public int minSubArrayLen(int target, int[] nums) {int len = nums.length;int count = 0;int ans = Integer.MAX_VALUE;for(int left = 0, right = 0; right < len; right++) {//进窗口count += nums[right];//出窗口while(count >= target) {ans = Math.min(ans, right - left + 1); //更新数据count -= nums[left++];}}return ans == Integer.MAX_VALUE ? 0 : ans;}
}
无重复字符的最长子串
https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/
解析:
如果使用暴力美学,还是前后指针法,由于这是求最长的字符串(也就是子串问题),对于子串子数组我们优先会想到滑动窗口算法。
在计算不重复的字符串的时候,前指针遇到不重复的字符,两个指针之间的距离就会自增,如果遇到重复的字符,后指针就会向前移动进行去重,按照暴力美学,前指针应该回退到后指针的前一个位置,但是有必要回退吗?首先因为经过后指针的去重,此时前后指针之间就没有重复的字符,这时候没有必要前指针回退,而这时候就是滑动窗口算法的特点。
使用滑动窗口,将不重复的字符加入到窗口中,当遇到重复的字符后指针就向前移动进行去重,再进行完进窗口和出窗口后,我们就可以更新最长长度了。
如何去重呢?大家可以使用Java 给我们提供的 HashSet,也就是哈希表进行去重。
补充:字符串转化成 字符数组的 方法 是 toCharArray().
本题使用 滑动窗口 + 哈希表,时间复杂度为O(2N) = O(N)
class Solution {public int lengthOfLongestSubstring(String ss) {int ans = Integer.MIN_VALUE;char[] s = ss.toCharArray();int len = s.length;Set<Character> set = new HashSet<>();for(int left = 0, right = 0; right < len; right++) {char ch = s[right];if(!set.contains(ch)) {set.add(ch); //进窗口} else {while(ch != s[left++]) {set.remove(s[left-1]);//出窗口}}//更新数据ans = Math.max(ans,right - left + 1);}return ans == Integer.MIN_VALUE ? 0 : ans;}
}
最大连续1的个数
https://leetcode.cn/problems/max-consecutive-ones-iii/description/
解析:
由于这是字数组问题,可以考虑滑动窗口,由于题目给定的 K 是最大零数字的承载量,所以如果超过这个量就需要进行去重操作,后指针直接前移,在零元素的前一个位置停下即可,这是出窗口,进窗口的条件很简单就是小于等于承载量的时候,更新数据放在最后,这样就保证这是一个符合题意的子数组。
承载量如何判断?引入一个变量 count 来记录当前的零元素个数
class Solution {public int longestOnes(int[] nums, int k) {int ans = Integer.MIN_VALUE;int len = nums.length;int count = 0;for(int left = 0, right = 0; right < len; right++) {//进窗口if(nums[right] == 0) {count++;}//出窗口if(count > k) {while(nums[left++] != 0) {;}count--;}//更新数据ans = Math.max(ans, right - left + 1);}return ans;}
}
将 x 减到 0 的最小操作数
https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/
解析:
由于每次只能减去最左端或者最右端的数值,所以如果最后有结果的话,那就是数组减去左区间和右边间,这两个区间的所有数字之和恰好等于 x
题目要求求出最小的操作数,说明左右区间的长度之和要最小。
如果正着求比较难的话,我们可以尝试反着求,也就是求中间部分最长,求中间部分一看就知道可以使用滑动窗口的方法。中间部分的数值应该等于 数组的所有数据之和减去 x ,我这里使用 target 变量来接受。
现在就是处理滑动窗口了,使用 sum 来接受此时 前后指针之间的所有的数据之和,先进窗口(sum 加数据),然后如果 sum > target 的时候就要出窗口(使用循环),最后更新数据的条件就是当 target == sum 时,进行更新数据。
细微条件处理:当数组的所有的数据之和小于 x 的时候,直接返回 -1 ,不能进入滑动窗口的部分,因为 target 计算后 sum - x = target < 0,在滑动窗口中 sum 始终大于 taget ,最终会一直出窗口,然后发生数组越界访问。
class Solution {public int minOperations(int[] nums, int x) {int sum = 0;for(int y : nums) {sum += y;}int target = sum - x;if(target < 0) {return -1;}int len = nums.length;int count = Integer.MIN_VALUE;sum = 0;for(int left = 0, right = 0; right < len; right++) {//进窗口sum += nums[right];//出窗口while(sum > target) {sum -= nums[left++];}//更新数据if(sum == target) {count = Math.max(count, right - left + 1);}}return count == Integer.MIN_VALUE ? -1 : len - count;}
}
水果成篮
https://leetcode.cn/problems/fruit-into-baskets/
解析:
最多只能装两种水果类型,题目要求我们要求出最大的采摘数量,显而易见的要使用滑动窗口。
进窗口,直接边遍历边进。
出窗口,就是遇到第三个水果类型,需要进行调整。
更新数据,在前两步骤做好就可以进行数据的更新了。
现在就要讨论用什么东西来装水果?
我们可以使用哈希表,Map 来接受水果类型和该水果目前的数量。
整体思路就是 哈希表加滑动窗口
class Solution {public int totalFruit(int[] fruits) {Map<Integer,Integer> map = new HashMap<>();int len = fruits.length;int count = Integer.MIN_VALUE;for(int left = 0, right = 0; right < len; right++) {//进窗口map.put(fruits[right],map.getOrDefault(fruits[right],0) + 1);//出窗口while(map.size() > 2) {map.put(fruits[left],map.get(fruits[left]) - 1);if(map.get(fruits[left]) == 0) {map.remove(fruits[left]);}left++;}//更新数据count = Math.max(count, right - left + 1);}return count;}
}
找到字符串中所有字母异位词
https://leetcode.cn/problems/find-all-anagrams-in-a-string/description/
解析:
还是子串问题,使用滑动窗口。由于涉及到字符串的查找,所以我们可以使用 toCharArray() 方法将字符串转化为数组,便于我们的使用。
如何存储两个字符串的内容:我们会想到使用哈希表,使用Map 来接受 字母 —— 出现数量 这个键值对,但是题目说了字符串只包含小写字母,那我们可以自己创建两个数组来模拟哈希表,而且使用数组更加方便。
如何比较两个字符串的内容?很多老铁一定想过使用循环遍历,而且我们还是使用数组来模拟哈希表,那就更加方法,这里介绍一种更好的方法,不需要循环遍历就可以比较成功。
使用一个变量来接收有效的字符数量。
如何使用?
我们在进出窗口的过程中顺便统计有效字符的个数,什么是有效的字符,我们需要和另一个哈希表的内容进行判断
这也就说明了我们要事先制作好一个哈希表,然后才开始遍历字符串 s
在遍历过程中,s 的哈希表对应的下标的元素先自增,然后开始判断,当这个字符也存在于 p 的哈希表中,并且 s 对应的元素值要小于等于 p 哈希表的,就算作有效字符
如果是大于 p 的,说明这个字符要么是重复字符要么是 p 哈希表不存在的字符。
出窗口:什么时候要出窗口?答:当当前的字符串长度大于 字符串 p 的长度,因为我们在进窗口的时候,只会统计有效字符个数,当有效字符个数等于 p 字符串的时候,才会更新数据,而此时满足当前 前后指针夹着的字符串全是有效字符 这个条件,只要当前的字符串的长度大于 p 字符串的长度的时候,就一定不是有效字符串,这时候就可以出窗口,顺便调整 s 哈希表的内容,由于此时的调整可能会删除掉有效字符,所以这个也要考虑有效字符的数量的变化,如果你要删除的字符对应的 s 哈希表的数值 小于等于 p 哈希表的时候 —— 有效字符数量就要自减,并且出窗口的次数实际上就是一次,所以用不到循环。
class Solution {public List<Integer> findAnagrams(String ss, String pp) {List<Integer> list = new ArrayList<>();char[] s = ss.toCharArray();char[] p = pp.toCharArray();int[] hash1 = new int[26];int[] hash2 = new int[26];for(char x : p) {hash2[x-'a']++;}int len = s.length;int count = 0;int size = p.length;for(int left = 0, right = 0; right < len; right++) {char ch = s[right];//进窗口if(++hash1[ch-'a'] <= hash2[ch-'a']) {count++;}//出窗口if(right - left + 1 > size) {if(hash1[s[left]-'a']-- <= hash2[s[left]-'a']) {count--;}left++;}//更新数据if(count == size) {list.add(left);}}return list;}
}
串联所有单词的子串
https://leetcode.cn/problems/substring-with-concatenation-of-all-words/description/
解析:
这道题目和上一道单词的异位词很相似,只不过这道题目是以单词为单位的。
不过我们如果将单词视为一个字符的话,思路和上面的一模一样。
使用两个哈希表存放单词。
如何划分字符串,由于 words 中每个单词的长度都是一致的,所以我们可以将字符串按照这个数量进行划分。
我们从暴力美学出发,如果要找出所有的子字符串,那么就需要两层循环。
在暴力美学的内层循环中我们要找到符合的子串,可以使用滑动窗口来求解,因为要比较的单词的长度都是一致的,所以我们可以按照单词的长度对字符串进行划分,也就是说在内层循环中使用滑动窗口的时候,指针每次移动都是加单词的长度
那么外层循环有必要遍历整个字符串吗?
答:没有必要,因为单词的长度是一致的,所以你单词的划分最多的情况就是单词的长度:
当外层循环遍历次数超过单词长度的时候,你会发现单词的划分和前面的循环重合,所以这些超过单词长度的循环次数是没有必要的,你如果硬要遍历的话,也可以,就是时间复杂度差了些。
所以继续优化的话,最外层循环次数就是单词的长度
最后就是要注意方法的使用了,如何划分字符串,使用 substring(), 哈希表的使用方法要注意 getOrDefault(),如果不存在的话可以返回默认值,但是不会加入到哈希表,其他的就不说了,不了解这些方法的,可以去我往期文章中查阅:String 类
JavaDS —— 二叉搜索树、哈希表、Map 与 Set
class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> list = new ArrayList<>();Map<String,Integer> mapW = new HashMap<>();for(String x : words) {mapW.put(x,mapW.getOrDefault(x,0) + 1);}int lenS = s.length();int len = words[0].length();Map<String,Integer> mapS = new HashMap<>();int count = 0;int size = words.length;for(int i = 0; i < len; i++) {mapS.clear();count = 0;for(int left = i, right = i; right + len <= lenS; right+=len) {String str = s.substring(right,right+len);mapS.put(str,mapS.getOrDefault(str,0) + 1); //进窗口if(mapS.get(str) <= mapW.getOrDefault(str,0)) {count++;} //出窗口if(right - left + 1 > len * size) {String ch = s.substring(left,left+len);if(mapS.get(ch) <= mapW.getOrDefault(ch,0)) {count--;}mapS.put(ch,mapS.get(ch)-1);left += len;}//更新数据if(count == size) {list.add(left);}}}return list;}
}
最小覆盖子串
https://leetcode.cn/problems/minimum-window-substring/
解析:
还是一个子串问题,使用滑动窗口,由于字符串全是英文字母组成,我们可以使用数组来模拟哈希表的映射关系。
这里我们可以使用 count 变量来统计有效字符个数。
因为题目要求出最小覆盖子串,所以难免会有重复或者不存在于 t 的字符出现,所以为了便于判断是否已经容纳好 t 的所有字符,减少循环出现,我们可以使用额外的变量来统计有效字符个数
进窗口:这个无需多言,直接进
出窗口和更新数据要小心点,当 count 等于有效字符个数的时候,我们要更新数据,那什么时候出窗口呢?如果按照之前的讨论进窗口——出窗口——更新数据是很难实现的,在最开始的时候,我就跟大家提到更新数据这个操作要按照实际情况来讨论,在这道题目就体现出来了。
首先更新完数据后,我们希望在下一个滑动窗口循环中能得到一个残缺的字符串,就是 count 要小于 有效字符总数这一个条件,所以在更新数据之后,我们可以进行出窗口的操作,要注意 count 的 变化,既然要达到 count 要小于 有效字符总数这个条件,我们可以在更新数据的时候写一个循环,正好随着出窗口的过程中一起将数据更新。
class Solution {public String minWindow(String ss, String tt) {String str = "";if(ss.length() < tt.length()) {return str;}int lenS = Integer.MAX_VALUE;int[] hash1 = new int[128];int[] hash2 = new int[128];char[] s = ss.toCharArray();char[] t = tt.toCharArray();for(char x : t) {hash2[x]++;}int len = s.length;int count = 0;int size = t.length;for(int left = 0, right = 0; right < len; right++) {//进窗口char ch = s[right];hash1[ch]++;if(hash1[ch] <= hash2[ch]) {count++;} while(count == size) {//更新数据if(lenS > right - left + 1) {lenS = right - left + 1;str = ss.substring(left,right+1);}//出窗口char x = s[left++];if(hash1[x]-- <= hash2[x]) {count--;}}}return str;}
}
小结
滑动窗口一般用于子数组或者子串问题上
滑动窗口的基本思路:
1.设置好两个指针 (left = 0, right = 0)
2.进窗口控制 right 指针
3.出窗口控制 left 指针
4.根据实际情况更新数据
一些注意事项:
如果发现字符串完全由字母组成,可以直接使用数组来模拟哈希表,这样做会方便很多
如果涉及到有效字符或者有效数字的时候,可以引入一个变量 来进行统计
相关文章:

算法【Java】 —— 滑动窗口
滑动窗口 在上一篇文章中,我们了解到了双指针算法,在双指针算法中我们知道了前后指针法,这篇文章就要提到前后指针法的一个经典的使用 —— 滑动窗口,在前后指针法中,我们知道一个指针在前,一个指针在后&a…...

Spring Aware接口执行时机
一. 介绍 Spring Aware 接口的执行时机有两处,都在 getBean() 中的 initializeBean() 中; 下面我们分析这两处时机; // ----------------------- AbstractAutowireCapableBeanFactory --------------------- protected Object initializeB…...

android FD_SET_chk问题定位
android FD_SET_chk问题定位 一、FD报错二、问题定位2.1 APM定位2.2 adb定位2.3. 代码获取FD数 三、FD优化 一、FD报错 App在运行中记录报错如下,FD_SET,这个问题大概是文件描述符(File Descriptor,简称FD)超过了最大…...

Chapter 39 Python多线程编程
欢迎大家订阅【Python从入门到精通】专栏,一起探索Python的无限可能! 文章目录 前言一、并行执行二、threading模块 前言 现代操作系统如 macOS、UNIX、Linux 和 Windows 等,均支持多任务处理。本篇文章详细讲解了并行执行的概念以及如何在 …...

STM32(二):GPIO
GPIO(General Purpose Input Output)通用输入输出口 1.可配置为8种输入输出模式,引脚电平:0V~3.3V,部分引脚可容忍5V,输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等,输入模式下…...

一文入门mysql 数据库
一、对数据库的操作 1.展示所有的数据库 show databases; 2.创建数据库 create database 数据库名 charset utf8; 3.删除数据库 drop database 数据库名; 4.查看当前使用的数据库 select database(); 5.使用数据库 use 数据库名; 二、对数据表的操作 1.展示所有表…...

通义千问( 四 ) Function Call 函数调用
4.2.function call 函数调用 大模型在面对实时性问题、私域知识型问题或数学计算等问题时可能效果不佳。 您可以使用function call功能,通过调用外部工具来提升模型的输出效果。您可以在调用大模型时,通过tools参数传入工具的名称、描述、入参等信息。…...

设置idea中放缩字体大小
由于idea没默认支持ctrl滚轴对字体调节大小,下面一起设置一下吧! 点击 文件 -> 设置 按键映射 -> 编辑器操作 -> 搜索栏输入f 点击减小字体大小 -> 选择增加鼠标快捷键 按着ctrl键,鼠标向下滚动后,点击确定即可 然后…...

frameworks 之getEvent指令
frameworks 之getEvent指令 指令解析源码追溯源码解析1.解析参数2.初始化ufds数组3.添加到poll 并做对应处理 通过 getEvent 可以识别按键基本命令和里面的关键信息 涉及到的类如下 system/core/toolbox/toolbox.csystem/core/toolbox/tools.hsystem/core/toolbox/getevent.c …...

tensorboard显示一片空白解决方案
OK艾瑞巴蒂 不知道看这个视频几个小土堆过来的,今天已经发了一篇博文探讨快速下载tensorboard了 下面用的时候叒出现问题了 from torch.utils.tensorboard import SummaryWriter writer SummaryWriter("logs")# writer.add_image() # Yx for i in range…...

C#编程中,如何实现一个高效的数据排序算法?
在C#编程中,可以使用内置的排序方法来实现高效的数据排序。最常用的方法是使用Array.Sort()和List<T>.Sort()。这些方法内部使用了快速排序算法(Quick Sort),它是一种非常高效的排序算法,平均时间复杂度为O(n lo…...

LookupError: Resource averaged_perceptron_tagger not found.解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

Leetcode JAVA刷刷站(39)组合总和
一、题目概述 二、思路方向 为了解决这个问题,我们可以使用回溯算法来找到所有可能的组合,使得组合中的数字之和等于目标数 target。因为数组中的元素可以无限制地重复选择,所以在回溯过程中,我们不需要跳过已经选择的元素&#x…...

Spring中AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory 是 Spring 框架中的一个抽象类,位于 org.springframework.beans.factory.support 包中。它实现了 AutowireCapableBeanFactory 接口,提供了一些通用的方法和逻辑,以支持 Spring 中的自动装配功能。 主要…...

PostgreSQL的walwriter和archiver进程区别
PostgreSQL的walwriter和archiver进程区别 在PostgreSQL中,walwriter和archiver进程是两个重要的后台进程,它们负责管理WAL(Write-Ahead Logging,预写日志)文件,但它们的职责和功能有所区别。理解这两个进…...

前端字体没有授权,字体版权检测(是否为方正字体)
1.截图系统中的首页和登录页面,主要是有字体的地方 2.在线字体版权检测地址:字体版权自动检测-求字体网 3.上传照片,开始对图片进行检测,每个账号有三次免费次数 4.检测完,直接查看检测报告即可, 报告中…...

在 SOCKS 和 HTTP 代理之间如何选择?
在 SOCKS 和 HTTP 代理之间进行选择需要彻底了解每种代理的工作原理以及它们传达的配置。只有这样,您才能轻松地在不同类型的代理之间进行选择。 本文概述了 HTTP 和 SOCKS 代理是什么、它们如何运作以及它们各自带来的好处。此外,我们将比较这两种代理类…...

C++适配windows和linux下网络编程TCP简单案例
C网络编程 网络协议是计算机网络中通信双方必须遵循的一套规则和约定,用于实现数据的传输、处理和控制。这些规则包括了数据格式、数据交换顺序、数据处理方式、错误检测和纠正等。网络协议是使不同类型的计算机和网络设备能够相互通信的基础,是网络通信…...

OpenDDS的GUID是如何构造的?
1、GUID、RepoID、GUID_t概念和关系 GUID(Global Unique IDentifiers)是RTPS规范约定的DDS对象的唯一性ID;RepoId(Repository IDentifiers)是Repo服务约定的DDS对象的唯一性ID;GUID和RepoId,都是基于GUID_t结构体定义,名称不同,但实质上是一样的。题外话: 无论是GUID还…...

初识MySQL(安装与配置环境)
嗨!今天我们进入一个新的领域---数据库。 首先来个小小铺垫。 我们平时存储东西的时候,一般用到文件。为什么有文件了,还继续要这个数据库呢? 很明显,文件有一些不好的地方,需要数据库来进行补充。 文件…...

druid+logback打印sql执行日志
druid 的LogFilter 为我们准备了四种logger类型,对应打印 datasource相关、connection相关、statement相关、resultset相关的日志。 druid.sql.Datasource:打印数据源相关的字段。 druid.sql.Connection:打印应用程序获得数据库连接的过程。…...

C++编程:无锁环形队列 (LockFreeRingQueue)的简单实现、测试和分析
文章目录 0. 概述1. 无锁环形队列概述1.1 无锁环形队列的特点1.2 无锁环形队列的优势与局限 2. LockFreeRingQueue 实现2.1 Enqueue 操作流程图2.2 Dequeue 操作流程图 3. 核心实现细节3.1 环形队列的大小调整3.2 索引计算3.3 原子操作与CAS3.4 线程让步 4. 测试示例程序4.1 实…...

植物生长时为什么会扭动?科学家解开令查尔斯·达尔文困惑的千古之谜
在一项新的研究中,来自美国和以色列的物理学家可能已经弄清了植物生长过程中的一种古怪行为–也是查尔斯-达尔文本人在其生命的最后几十年里所好奇的一个谜:对于许多人类来说,植物可能看起来静止不动,甚至有点无趣。但实际上&…...

SAP LE学习笔记02 - WM和库存管理(IM)之间的关系,保管Lot(Quant)
上一章学习了LE的基础知识。 1,LE的概述,LE里面包含下面3个大的模块 - LE-WM 仓库管理 / - LE-SHP 发货/ - LE-TRA 运输 2,仓库的结构 - 仓库番号 / -保管域Type(存储区域)/ - 保管区画(存储区)/ - 棚番(Storage Bin 仓位&…...

Span<T> 是 C# 7.2 引入的重要类型
Span<T> 是 C# 7.2 引入的一个非常重要的类型,它提供了一种低开销、类型安全的方式来操作连续的内存区域。Span<T> 本质上是一个结构体,它封装了一个内存段的引用(通过指针)以及该内存段的长度。由于它直接操作内存&a…...

Python办公自动化:初识 `openpyxl`
1.1 什么是 openpyxl? openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的 Python 库。它允许我们通过 Python 脚本自动化处理 Excel 文件,包括创建新的工作簿、修改现有的工作簿、格式化单元格、处理公式和图表等功能。这对于办公自动化、…...

Pocketbase实战体验:内置数据库与实时功能如何超越传统MySQL
Pocketbase 是一个开源的实时后端服务器,内置了数据库、实时订阅、用户认证、RESTful API 等功能,而 MySQL 是一个广泛使用的关系数据库管理系统。以下是 Pocketbase 相对于 MySQL 的一些潜在优点: 完整的后端解决方案 一体化:P…...

ChatGPT 3.5/4.0 新手使用手册(详细版)
1. 什么是 ChatGPT? ChatGPT是由 OpenAI 开发的先进人工智能语言模型,能够理解并生成自然语言文本。它可以帮助你进行写作、回答问题、提供建议,甚至参与对话。ChatGPT 3.5 和 4.0 是两个不同版本,它们都拥有强大的语言处理能力&…...

【Java学习】Stream流详解
所属专栏:Java学习 Stream流是JDK 8引入的一个概念,它提供了一种高效且表达力强的方式来处理数据集合(如List、Set等)或数组。Stream API可以以声明性方式(指定做什么)来处理数据序列。流操作可以被分为两大…...

Oracle(69)什么是表压缩(Table Compression)?
表压缩(Table Compression)是一种数据库优化技术,用于减少表数据的存储空间和提高I/O性能。通过压缩表数据,可以显著减少存储需求,并在某些情况下提高查询性能,特别是对于只读或主要是读取操作的表。表压缩…...