【java算法专场】滑动窗口(下)

目录

水果成篮

算法分析

算法步骤

示例

算法代码

找到字符串中所有字母异位词

算法分析

算法步骤

示例

算法代码

优化

算法代码

串联所有单词的子串

算法分析

算法步骤

示例

算法代码

 最小覆盖子串

算法分析

算法步骤

示例

算法代码


算法分析

这道题其实就是在数组中找连续的的最长子数组,且子数组里的不同数字不能超过两个。 如果采用暴力枚举数组中的每一个字串,并借助哈希表来存储子数组中有多少种水果,并且每种水果的数量有多少。时间复杂度会达到O(n),因此,可以在暴力枚举的举出上进行优化,使用滑动窗口来解决。

算法步骤

  1. 初始化:设置双指针leftright并初始化为0,表示滑动窗口的边界。设置一个空的HashMap来存储水果种类及数量。定义ans并初始化为0,用于记录能够采摘的数目。
  2. 右边界(right)移动:让right往右移动,并将nums[right]在HashMap中的数量+1
  3. 判断水果种类:当HashMap.size()>2时,说明此时采摘的水果中有3种,需要去除一种。此时就需要让left往右移动,并将nums[left]在HashMap中的数量-1,当nums[left]对应的数量为0时,说明此时已经将一种水果去除,调用 map.remove(fruits[left]),将水果移除。
  4. 更新结果:在右指针right遍历数组的时,每次都需要更新一下ans的值,判断ans此时的值是否比(right-left+1)大,若大于则进行更新。
  5. 遍历结束:当right遍历完数组,此时返回ans的值即可。

时间复杂度:O(n),n是数组长度,每个元素最多只会被遍历两次。在扩大窗口的时候,right会遍历一遍数组。在最坏情况下,left也只会遍历一遍数组。

空间复杂度:O(1),这里只用到了几个固定的变量,虽然使用了HashMap,但最多也只存储了三种。

示例

以[1,2,3,2,2]为例

第一步:初始化

让left=right=0,定义一个map(哈希表),初始化ans=0;

第二步:扩大窗口,判断种类

让right往右移,在map中不超过2种时,同时更新ans值。

 第三步:左指针移动

此时map中种类超过2种,需要移动左指针,直到map中某个水果的数量为0。将数量为0的水果从map中移除。

 第四步:右指针继续移动,重复二三步,直到右指针right遍历完数组。当遍历完数组,此时ans=4.即在数组中[2,3,2,2]。

第五步:返回结果,将ans=4返回。

算法代码

/*** 计算最长的水果数组段,其中只包含两种不同的水果。* * @param fruits 水果数组,数组中的每个元素代表一种水果。* @return 返回最长的水果数组段的长度。*/
public int totalFruit(int[] fruits) {/* 初始化结果变量为0,用于记录最长的水果数组段的长度 */int ans = 0;/* 初始化左指针为0,用于标记当前水果数组段的起始位置 */int left = 0;/* 初始化右指针为0,用于标记当前水果数组段的结束位置 */int right = 0;/* 使用HashMap来记录每种水果的数量,键为水果的类型,值为该类型水果的数量 */HashMap<Integer, Integer> map = new HashMap<>();/* 遍历水果数组,更新HashMap和计算最长数组段的长度 */for (; right < fruits.length; right++) {/* 将右指针指向的水果添加到HashMap中,如果该水果已存在,则数量加1 */map.put(fruits[right], map.getOrDefault(fruits[right], 0) + 1);/* 当HashMap中的水果种类超过2种时,需要缩小数组段直到满足条件 */while (map.size() > 2) {/* 从HashMap中减去左指针指向的水果的数量,如果数量减到0,则从HashMap中移除该水果 */map.put(fruits[left], map.getOrDefault(fruits[left], 0) - 1);if (map.get(fruits[left]) == 0) {map.remove(fruits[left]);}/* 左指针向右移动,缩小数组段 */left++;}/* 更新最长数组段的长度 */ans = Math.max(ans, right - left + 1);}/* 返回最长数组段的长度 */return ans;
}

找到字符串中所有字母异位词

算法分析

这道题题意说明了要在字符串s中找到所有p的异位词。所以这道题可以使用暴力枚举+哈希表,但是时间复杂度达到O(n^2),我们可以使用滑动窗口+哈希表来使用。

算法步骤

  1. 初始化:定义双指针leftright并初始化为0,将两个字符串s和p转化为字符数组ss和pp,且这里需要用到两个hash表,这里设置为hash1和hash2,hash1用来存放字符串p的字符个数,hash2用来后续的遍历操作。【这里由于限制了是小写字母,所以hash数组的大小可以设置为26】定义变量m记录p的长度。定义ans顺序表,用来存放在符合条件的子串的起始位置。
  2. 扩展右边界:右指针right往右移动,用变量in记录字符nums[right],将in字符存进hash2中,但需要注意在存放时需要让in-‘a’,即hash2[in-'a']。
  3. 处理窗口:由于这里是限定了窗口的大小,即字符串p的长度。所以当right-left+1大于m时,说明窗口过大,需要进行缩小窗口,让left往右移动一位,同时需要将out【这里定义变量out字符为hash2[left]】在hash2中➖1。当right-left+1==m,说明此时窗口大小刚好等于p的长度,调用equal方法来判断hash1和hash2是否相等,若相等,则将left添加到ans中

时间复杂度:O(n),n为s的长度,每个字符最多被访问2次。

空间复杂度:O(1),虽然使用hash1和hash2数组,但都是固定大小的,且使用的变量固定。

示例

算法代码

 /*** 查找字符串s中所有p的字母异位词的起始索引。** @param s 输入的字符串* @param p 指定的模式字符串* @return 返回一个包含所有字母异位词起始索引的列表*/public List<Integer> findAnagrams1(String s, String p) {List<Integer> ans = new ArrayList<>(); // 用于存储结果的列表int left = 0; // 窗口的左边界int right = 0; // 窗口的右边界char[] ss = s.toCharArray(); // 将字符串s转换为字符数组char[] pp = p.toCharArray(); // 将字符串p转换为字符数组int[] hash1 = new int[26]; // 用于存储模式字符串p的字符计数for (char ch : pp) hash1[ch - 'a']++; // 统计模式字符串p中每个字符的数量int[] hash2 = new int[26]; // 用于存储当前窗口中字符的计数int m = pp.length; // 模式字符串p的长度while (right < s.length()) { // 窗口右边界不超过字符串s的长度char in = ss[right]; // 当前纳入窗口的字符hash2[in - 'a']++; // 窗口内字符计数加一if (right - left + 1 > m) { // 当窗口大小超过模式字符串p的长度时char out = ss[left++]; // 移除窗口最左边的字符hash2[out - 'a']--; // 窗口内字符计数减一}if (right - left + 1 == m) { // 当窗口大小等于模式字符串p的长度时if (Arrays.equals(hash1, hash2)) { // 比较窗口内字符计数和模式字符串的字符计数ans.add(left); // 如果相同,则将窗口左边界添加到结果列表中}}right++; // 窗口右边界向右移动}return ans; // 返回结果列表}

优化

当然,在上述中,若面对比较复杂的问题,不是最优解法,可以对其进行优化。

主要是第二、三步进行处理

在上述算法中,我们是将ss[right]的值直接放在hash2中,但我们可以进行优化:

  • 定义一个count,用来判断判断当前窗口是否符合条件,当count=m时,说明找到了符合条件的子串,将left添加到ans中即可;count++的前提条件是hash2中的计数小于等于hash1中的计数,才能让count++。
  • 当right-left+1>m,即窗口过大时,要缩小窗口,但同时需要判断此时以ss[left]为下标的hash2中的计数是否小于等于hash1中对应位置的计数,若小于,则需要让count--。

算法代码

/*** 查找字符串s中所有p的字母异位词的起始索引。** @param s 输入的字符串* @param p 指定的字母异位词模式* @return 返回一个包含所有字母异位词起始索引的列表*/public List<Integer> findAnagrams(String s, String p) {List<Integer> ans = new ArrayList<>();char[] ss = s.toCharArray();char[] pp = p.toCharArray();// 初始化hash1数组,用于存储模式p中每个字符出现的次数int[] hash1 = new int[26];for (char ch : pp) {hash1[ch - 'a']++;}// count用于记录当前窗口中满足p中字符比例的子串数量int count = 0;int m = pp.length;// hash2数组用于存储当前窗口中每个字符出现的次数int[] hash2 = new int[26];int left = 0;int right = 0;// 滑动窗口遍历字符串sfor (; right < s.length(); right++) {char in = ss[right];// 当前字符加入窗口,如果其出现次数不超过p中对应字符的次数,则count增加// 判断是否满足条件,进窗口if (++hash2[in - 'a'] <= hash1[in - 'a']) {count++;}// 如果窗口大小超过了p的长度,则需要移除最左边的字符// 判断长度,if (right - left + 1 > m) {char out = ss[left++];// 移除字符,如果移除后窗口中该字符出现次数不超过p中对应字符的次数,则count减少if (hash2[out - 'a']-- <= hash1[out - 'a']) {count--;}}// 如果当前窗口中满足p中字符比例的子串数量等于p的长度,则当前窗口起始索引加入结果列表if (count == m) {ans.add(left);}}return ans;}

串联所有单词的子串

算法分析

这道题与前一道题优化算法的思路基本一样,要求在字符串s中找到words字符串数组中所有字符串任意顺序串联起来的子串。

算法步骤

  1. 初始化:设置双指针leftright并初始化为0;设置两个HahsMap<String,Integer>,map1用来存放words字符串数组中的字符串及其个数,map2用来存放s字符串中符合条件的字符串;设置ans顺序表,用来存放符合条件的子串起始位置。设置count并初始化为0,用来记录符合条件的子串个数;定义len并初始化为words[0].length()[即字符串数组中字符串的长度],定义m并初始化为words数组的长度
  2. 预处理:将words字符串数组中的字符串存放到map1中。
  3. 滑动窗口遍历字符串
  • 由于在s字符串中,我们不知道words数组中字符串在s中是在起始位置上开始的,所以根据len,可以有len种起始位置。示例:

  • 每个单词的长度为len,所以设置双指针在移动时,步长为len。
  • 遍历每一个有可能的起始位置i,并每次定义map2用来存放不同起始位置下的单词。 
  • 让left=right=i,count=0,移动窗口,并将分割出来的单词in放进map2中,判断in在map2中的数量是否小于等于map1的数量,若小于,则让count++;
  • 判断当前窗口的长度(right-left+1)是否大于字符串数组中所有字符串的总长度(len*m),若大于,说明窗口过大,需要将【left,left+len】位置的字符出窗口。需要出窗口的字符串out,需要判断是否在map2中的数量小于等于map1的数量,若小于,则让count--;当出完窗口后,需要让out在map2中对应的数量-1,再让left+=len;
  • 当count等于m【words数组的长度】,说明此时已经找到了符合条件的串联子串,将left添加到ans中。

4.返回结果:当遍历完所有可能的情况,此时返回结果ans即可。

示例

以s = "barfoothefoobarman", words = ["foo","bar"]为例

第一步:初始化,并预处理

在初始化完所需的变量之后,将words数组中的字符串存放到map1中,得到

map1={["foo",1],["bar",1]}

第二步:滑动窗口遍历s(此处只列举第一种起始位置情况)

  1. 此时left=right=i=0,count=0(此处len为3)
  2. 截断s中[right,right+len)位置的字符串作为in,in=“bar”,将in存放到map2中,map2={["bar",1]},并且判断一下in在map2中的数量是否小于等于在map1中的数量,若小于等于,则让count++;
  3. 判断窗口的大小(right-left+1=3-0+1=4<len*m=4*2=8,不需要进行出窗口操作。
  4. 由于count此时依旧为0,小于m=2,不满足条件,left不用添加到ans中。
  5. 重复上述操作。
  6. 第二次:map2={["bar",1],["foo",1]} count=2  添加left到ans中 ans=[0]
  7. 第三次:map2={["bar",1],["foo",1],["the",1]}  count=2 
  8. 出窗口:map2={["foo",1],["the",1]}  count=1 
  9. 第四次: map2={["foo",2],["the",1]}  count=1
  10. 出窗口: map2={["foo",1],["the",1]}  count=1
  11. 第五次: map2={["foo",1],["the",1],["bar",1]}  count=2  
  12. 出窗口:map2={["foo",1],["bar",1]}  count=2 添加left到ans中,此时left=9 ans=[0,9]
  13. 第六次:  map2={["foo",1],["bar",1],["man",1]}  count=2
  14. 出窗口:map1={["bar",1],["man",1]}  count=1
  15. 此时right已经走到s的末尾,遍历结束,返回结果ans=[0,9]。

算法代码

 /*** 查找所有包含给定单词数组中所有单词的子字符串的起始索引。** @param s 输入的字符串。* @param words 给定的单词数组。* @return 包含所有单词的子字符串的起始索引列表。*/public List<Integer> findSubstring(String s, String[] words) {// 用于存储结果的列表List<Integer> ans = new ArrayList<>();// 统计每个单词出现的次数// 借助hash表HashMap<String,Integer> map1=new HashMap<>();//统计words中有多少单词for(String word:words) map1.put(word,map1.getOrDefault(word,0)+1);//用于后序操作// 单词的长度int len=words[0].length();// 单词长度// 单词的数量int m=words.length;// 当前窗口中包含的所有单词的数量int count=0;// 窗口的左右边界int left=0;int right=0;// 遍历字符串s,寻找符合条件的子字符串for(int i=0;i<len;i++) {// 当前窗口中单词的统计信息HashMap<String, Integer> map2 = new HashMap<>();// 移动窗口,查找符合条件的子字符串for (left = i, right = i,count=0; right+ len <= s.length() ; right += len) {// 窗口中的当前单词//进窗口维护String in = s.substring(right, right + len);// 更新当前单词在窗口中的统计信息map2.put(in, map2.getOrDefault(in, 0) + 1);// 如果当前单词在窗口中的数量不超过其应有数量,则增加countif (map2.get(in) <= map1.getOrDefault(in, 0)) count++;// 如果窗口大小超过了最大允许值,则需要移除左边界上的单词//出窗口if (right - left + 1 > len*m) {// 移除的单词String out = s.substring(left, left + len);// 如果移除的单词在窗口中的数量不超过其应有数量,则减少countif (map2.get(out) <= map1.getOrDefault(out, 0)) count--;// 更新窗口中移除单词的统计信息map2.put(out, map2.get(out) - 1);// 移动左边界left += len;}// 如果当前窗口中包含了所有单词,则将左边界索引添加到结果列表中if (count == words.length) ans.add(left);}}// 返回结果列表return ans;}

 最小覆盖子串

算法分析

本题要求在s中找到t的最小覆盖子串,我们可以使用暴力枚举+hash表来实现,但时间复杂度会达到O(n^2),我们可以在此进行优化,使用滑动窗口。

算法步骤

  1. 初始化:设置双指针leftright,并初始化为0作为滑动窗口的边界;将s和t字符串转化为字符数组ss和tt方便操作;设置两个hash表(hash1和hash2),长度为128,hash1用来统计t中的字符;设置begin并初始化为-1,mixLen初始化为Integer.MAX_VALUE,作为最小覆盖子串的起始位置以及末尾位置;定义count(计数器)并初始化为0,用来匹配符合条件的字符。

  2. 预处理:设置kind并初始化为0,用来计算t中的字符种类有多少种。将tt字符数组中的字符通过hash1进行计数,当hash[ch]为0时,kind++;

  3. 处理窗口:右指针移动,并将in【in=ss[right]】添加到hash2中,同时判断in在hash2中的数量是否与hash1的相同,若相同,则让count++。当计数器count等于kind时,说明已经找到了符合条件的子串,此时,若minLen==-1或者right-left+1<minLen时,更新begin=left和minLen=right-left+1;当添加完后,缩小窗口,让left往右移,若hash2[left]==hash1[left],需要让count--,同时让left++;寻找更小的覆盖子串。

  4. 重复上述操作,直到遍历完s。

  5. 返回结果:若minLen==-1,说明没有找到符合条件的子串,如不为0,则返回[begin,begin+minLen)的截断字符串。

时间复杂度:O(n),n为ss的长度,每个字符最多被遍历两次。

空间复杂度:O(1),虽然使用了hash,但长度是固定的。

示例

以s = "ADOBECODEBANC", t = "ABC"为例

第一步:初始化

  • left=right=0
  • 初始化hash1和hash2并设置长度为128.
  • 将s和t转化为字符数组ss和tt
  • kind=0,用于记录不同字符的种类,遍历数组tt并计数到hash1中,此处kind=3,hash['A']=1,hash['B']=1,hash['C']=1.

第二步:处理窗口

  1. 使用双指针left和right,扩大窗口,并将字符in计数到hash2中,若in在hash2的数量等于hash1的数量,则让count++;
  2. 当count=kind时,说明此事已经找到了匹配的覆盖子串,判断right-left+1<minLen或者minLen=-1时,则进行替换,让begin=left,minLen=right-left+1;当判断完之后,移除左窗口out,同时判断out在hash2和hash1的计数是否相等,若相等,则让count--。
  3. 重复上述操作,当right遍历完s字符串时,结束循环。
  4. 返回结果,此时,由于begin不为-1,根据begin和minLen,截取s中此位置的字符串,为“BANC”。

算法代码

  /*** 寻找字符串s中包含字符串t所有字符的最短子串。* @param s 原始字符串* @param t 目标字符串,需要在原始字符串中找到包含所有这些字符的最短子串* @return 返回最短子串的字符串,如果不存在则返回空字符串*/public String minWindow(String s, String t) {// 初始化两个字符数组,用于统计字符串t和字符串s中字符出现的次数int[] hash1=new int[128];int[] hash2=new int[128];// 将字符串t转换为字符数组,方便后续处理char[] tt=t.toCharArray();// 计算字符串t中不同字符的数量int kind=0;for(char ch:tt){if(hash1[ch]++==0) kind++;}// 将字符串s转换为字符数组,方便后续处理char[] ss=s.toCharArray();// 初始化指针begin和minlen,begin用于标记最短子串的起始位置,minlen用于记录最短子串的长度int begin=-1;int minlen=Integer.MAX_VALUE;// 初始化滑动窗口的左指针left、右指针right和当前窗口中包含t中字符的数量countint left,right,count;for(left=0,right=0,count=0;right<ss.length;right++){char in=ss[right];// 当前字符在窗口中出现的次数等于在t中出现的次数时,count加1if(++hash2[in]==hash1[in]) count++;// 当窗口中包含了t中所有字符时while(count==kind){// 更新最短子串的起始位置和长度if(right-left+1<minlen||minlen==-1){begin=left;minlen=right-left+1;}// 移动窗口的左指针,并更新count和hash2数组char out=ss[left++];if(hash2[out]--==hash1[out]) count--;}}// 根据begin和minlen的值,返回最短子串或空字符串if(begin==-1){return  new String();}else{return s.substring(begin,begin+minlen);}}

以上就是本篇所有内容,滑动窗口的题目就先到这了,后序若有相关题目,将会更新!

若有不足,欢迎指正~ 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—透明背景生成工具

大家好&#xff0c;我是设计师阿威 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可以…

NSIS 之 NsDialogs 常见问题解答

如何启用/禁用控件 使用标准 NSIS EnableWindow 命令。 NSDialogs 允许您弹出通过 ${NSD_Create*} 创建的控件的 hwnd (句柄)。EnableWindow 将 hwnd 作为其参数之一。通过它&#xff0c;您可以轻松启用/禁用控件。 !include "nsDialogs.nsh" !include "winm…

代码随想录:图论_01基础

图论基础 图的存储 邻接矩阵 使用 二维数组 来表示图结构。 邻接矩阵是从节点的角度来表示图&#xff0c;有多少节点就申请多大的二维数组。为了节点标号和下标对齐&#xff0c;我们申请 n 1 * n 1 这么大的二维数组。 vector<vector<int>> graph(n 1, vector…

特斯拉的选择:.NET技术栈的工业级魅力

简述 在全球科技巨头的竞技场上&#xff0c;特斯拉以其创新精神和卓越技术引领着电动汽车和可再生能源行业。而在这场技术革命的背后&#xff0c;特斯拉的技术栈选择尤为引人注目。本文将深入探讨特斯拉为何青睐.NET技术栈&#xff0c;并分析这一选择背后的战略考量。 技术栈的…

【Linux 文件读写描述符重定向 Linux 一切皆文件缓冲区】

文章目录 一、文件的读写操作二、文件描述符三、文件重定向四、理解 Linux 一切皆文件五、文件缓冲区 一、文件的读写操作 文件内容属性 当文件没有被操作的时候&#xff0c;一般文件还是在磁盘当中 文件操作文件内容的操作文件属性的操作&#xff0c;文件操作有可能即改变内容…

二叉树---后序遍历(递归与迭代)

题目&#xff1a;给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 思路一&#xff1a;递归法。 代码&#xff1a; public List<Integer> postorderTraversal(TreeNode root) {List<Integer> resultnew ArrayList<>();postOrder(root,…

如何利用Gunicorn的日志记录监控Web应用

如何利用Gunicorn的日志记录监控Web应用 引言 在构建和维护Web应用时&#xff0c;日志记录是一个至关重要的工具。它不仅可以帮助开发者了解应用的运行状态&#xff0c;还能迅速定位和解决问题。Gunicorn作为一个流行的Python WSGI HTTP服务器&#xff0c;提供了丰富的日志记…

代码运行故障排除:PyCharm中的问题解决指南

代码运行故障排除&#xff1a;PyCharm中的问题解决指南 引言 PyCharm&#xff0c;作为一款流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;提供了强大的工具来支持Python开发。然而&#xff0c;即使是最先进的IDE也可能遇到代码无法运行的问题。这些问题可能由多…

《python程序语言设计》2018版第5章第55题利用turtle黑白棋盘。可读性还是最重要的。

今天是我从2024年2月21日开始第9次做《python程序语言设计》作者梁勇 第5章 从2019年夏天的偶然了解python到2020年第一次碰到第5章第一题。彻底放弃。再到半年后重新从第一章跑到第五章&#xff0c;一遍一遍一直到今天2024.7.14日第9次刷第五章。 真的每次刷完第五章感觉好像…

【C语言】<常量> 之群英荟萃

目录 1. 数值常量&#xff08;Numeric Constants&#xff09;1.1 整型常量&#xff08;Integer Constants&#xff09;1.2 浮点型常量&#xff08;Floating-point Constants&#xff09; 2. 字符常量&#xff08;Character Constants&#xff09;3. 字符串常量&#xff08;Stri…

【JavaScript】解决 JavaScript 语言报错:Uncaught SyntaxError: Unexpected token

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 缺少必要的语法元素2. 使用了不正确的字符或符号3. JSON 格式错误4. 字符串未正确闭合 四、解决方案与预防措施1. 检查语法元素2. 正确使用符号和字符3. 修正 JSON 格式4. 字符串闭合 五、示例代码和实践建议…

android13 文件管理器无法安装apk 奔溃问题

总纲 android13 rom 开发总纲说明 目录 1.前言 2.我们简单写个apk测试下 3.排查客户apk 4.frameworks源码排查 5.编译验证 6.彩蛋 1.前言 客户提供的文件管理apk不能安装apk文件,一点击就奔溃。 2.我们简单写个apk测试下 private void installApk(File apkFile) {i…

映美精黑白相机IFrameQueueBuffer转halcon的HObject

映美精黑白相机&#xff0c;用wpfhalcon开发取图 1.到官网下载&#xff0c;开发包 1sdk 2c开发例子 3c#开发例子 引入TIS.Imaging.ICImagingControl35.dll 3.ICImagingControl使用这个类控制相机 /// <summary> /// 相机控制 /// </summary> public ICImagingC…

MySQL的插入(DML)

1.给指定字段添加数据 这个就是&#xff0c;想插入所对应的字段&#xff0c;就插入所对应的数值。先把字段列出来&#xff0c;不一定是全部的字段&#xff0c; 然后插入想要的值&#xff0c;注意&#xff0c;只能插入一行。 INSERT INTO 表名 (字段1,字段2,.....) VALUES(值…

将swagger注解导入apifox的IDEA配置

在使用IDEA开发中&#xff0c;经常需要将后端接口导出到Apifox&#xff0c;以便于测试。将swagger注解内容导出到Apifox中&#xff0c;需要进行以下设置: file->settting打开对话框&#xff0c;选择Other Settings -> Apifox Help&#xff0c;如下图&#xff1a; 2.选…

【Python】ftplib的使用

仅描述基础要点&#xff0c;备忘。 python自带ftplib库&#xff0c;可实现ftp读写。 1 要点 ftp未使用默认端口21时&#xff0c;需显示指定端口。ftp路径带有中文&#xff0c;可能需要设置ftp的encoding属性为 gbk。ftplib不支持递归创建目录&#xff0c;需手动创建层级目录…

NAS 必备导航页 Homarr 可视化配置 布局简单且美观

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 之前给大家介绍了 Homepage,但是 Homepage 的每一个链接的添加以及整体的布局都依赖 yaml 文件,而且官方文档关于 yaml 配置项也只有英文。对于没有基础的用户来说,想要配置成自己喜欢的布局有些困难。而今天介绍…

【软件测试】自动化测试常用函数 -- 详解

一、WebDriver API 一个简单自动化脚本的构成&#xff1a; 脚本解析 # coding utf-8 from selenium import webdriver import time browser webdriver.Firefox() time.sleep(3) browser.get("http://www.baidu.com") time.sleep(3) browser.find_element_by_id(…

数据实时化是必要还是偏见?

数据实时化是必要还是偏见&#xff1f; 一、前言二、数据仓库的起源三、数据架构的演进四、数据实时化的必要性五、总结 本文主要基于数据仓库的起源和数据架构的演进来聊聊&#xff0c;数据实时化是否真的必要&#xff1f;是"过度优化"、“实时偏见"还是"…

元组-预习

# 元组 tuple() # 定义 tu () # 空元组 tu1 (1, 2, 3) # 一旦初始化&#xff0c;不可再改变# 索引 print(tu1[0]) # 1 print(tu1[-1]) # 3 # print(tu1[3]) # 报错 超出索引范围# 切片 tu2 (1, 2, 3, 4, 5) print(tu2[0:2])# 不允许改变tu2[0] 6 # TypeError: tuple …