14.面试算法-字符串常见算法题(三)

1. 字符串回文问题

1.1 LeetCode.125. 验证回文串

回文问题在链表中是重点,在字符串中同样是个重点。当初我去美团面试第一轮技术面的第一个算法题就是让写判断字符串回文的问题。

这个本身还是比较简单的,只要先转换成字符数组,然后使用双指针方法从两头到中间比较就行了。也许是过于简单了吧,面试时经常被加餐,例如LeetCode里的两道题。 一个是普通的验证回文串,第二个是找最长的子回文串。第二个问题需要动态规划等技术,有点难度,如果感兴趣可以自行去了解下,这里先看一下基本的。

题目:

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个回文串。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是回文串 ,返回 true ;否则,返回 false 。

示例1:
输入 : “A man, a plan, a canal: Panama” 输出 : true
解释: “amanaplanacanalpanama” 是回文串
示例2:
输入 : “race a car” 输出 : false
解释: “raceacar” 不是回文串
示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 “” 。
由于空字符串正着反着读都一样,所以是回文串。

分析

最简单的方法是对字符串 s 进行一次遍历,并将其中的字母和数字字符进行保留,放在另一个字符串 sgood 中。这样我们只需要判断 sgood 是否是一个普通的回文串即可。

判断的方法有两种。第一种是使用语言中的字符串翻转 API 得到 sgood 的逆序字符串 sgood_rev,只要这两个字符串相同,那么 sgood 就是回文串。

class Solution {public boolean isPalindrome(String s) {StringBuffer sgood = new StringBuffer();int length = s.length();for (int i = 0; i < length; i++) {char ch = s.charAt(i);if (Character.isLetterOrDigit(ch)) {sgood.append(Character.toLowerCase(ch));}}StringBuffer sgood_rev = new StringBuffer(sgood).reverse();return sgood.toString().equals(sgood_rev.toString());}
}

第二种是使用双指针。初始时,左右指针分别指向 sgood 的两侧,随后我们不断地将这两个指针相向移动,每次移动一步,并判断这两个指针指向的字符是否相同。当这两个指针相遇时,就说明 sgood 时回文串。

class Solution {public boolean isPalindrome(String s) {StringBuffer sgood = new StringBuffer();int length = s.length();for (int i = 0; i < length; i++) {char ch = s.charAt(i);if (Character.isLetterOrDigit(ch)) {sgood.append(Character.toLowerCase(ch));}}int n = sgood.length();int left = 0, right = n - 1;while (left < right) {if (Character.toLowerCase(sgood.charAt(left)) != Character.toLowerCase(sgood.charAt(right))) {return false;}++left;--right;}return true;}
}

2. 字符串简单搜索问题

我们为什么叫简单搜索问题呢?因为字符串的有些搜索问题非常复杂,需要dp或者更高级的算法,例如字符匹配等等,因此这里我们先看几个简单的情况。

2.1 LeetCode387. 字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例 1:
输入: s = “leetcode”
输出: 0
示例 2:
输入: s = “loveleetcode”
输出: 2
示例 3:
输入: s = “aabb”
输出: -1

提示:s 只包含小写字母

我们可以对字符串进行两次遍历,在第一次遍历时,我们使用哈希映射统计出字符串中每个字符出现的次数。在第二次遍历时,我们只要遍历到了一个只出现一次的字符,那么就返回它的索引,否则在遍历结束后返回 -1。

class Solution {public int firstUniqChar(String s) {Map<Character, Integer> frequency = new HashMap<Character, Integer>();for (int i = 0; i < s.length(); ++i) {char ch = s.charAt(i);frequency.put(ch, frequency.getOrDefault(ch, 0) + 1);}for (int i = 0; i < s.length(); ++i) {if (frequency.get(s.charAt(i)) == 1) {return i;}}return -1;}
}

2.2 LeetCode58. 最后一个单词的长度

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

示例 1:
输入:s = “Hello World”
输出:5
解释:最后一个单词是“World”,长度为 5。
示例 2:
输入:s = " fly me to the moon "
输出:4
解释:最后一个单词是“moon”,长度为 4。
示例 3:
输入:s = “luffy is still joyboy”
输出:6
解释:最后一个单词是长度为 6 的“joyboy”。

分析
这个题还是比较简单的,反向遍历。题目要求得到字符串中最后一个单词的长度,可以反向遍历字符串,寻找最后 一个单词并计算其长度。

由于字符串中至少存在一个单词,因此字符串中一定有字母。首先找到字符串中的最后一个字母,该字母即为最后一个单词的最后一个字母。

从最后一个字母开始继续反向遍历字符串,直到遇到空格或者到达字符串的起始位置。遍历到的每个字母都是最后一个单词中的字母,因此遍历到的字母数量即为最后一个单词的长度。

class Solution {public int lengthOfLastWord(String s) {int index = s.length() - 1;while (s.charAt(index) == ' ') {index--;}int wordLength = 0;while (index >= 0 && s.charAt(index) != ' ') {wordLength++;index--;}return wordLength;}
}

3. 旋转和重排

3.1 [剑指Offer】 58. 左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例1:
输入 : s = “abcdefg”, k = 2
输出 : “cdefgab”
示例2:
输入 : s = “lrloseumgh”, k = 6
输出 : “umghlrlose”

本题有多种方式处理的,最直观的方式是前面剪贴下来的若干字符和后面的字符保存到两个数组里,然后再按照要求合并就行了。这个在go、JavaScript 、python等语言中有切片的操作,可以非常方便地处理,java中虽然没有切片,但是可以通过子串来实现相同的功能。

class Solution {public String reverseLeftWords(String s, int n) { if (s == null || s.length() == 0) {return s;}return s.substring(n, s.length()) + s.substring(0, n);}
}

第二种方式是通过StringBuilder来实现拼接,先将第k个之后的元素添加进来,然后再将前k个添加进来,代码如下:

class Solution {public String reverseLeftWords(String s, int n) { if (s == null || s.length() == 0) {return s;}StringBuilder res = new StringBuilder();for(int i = n; i < s.length(); i++)res.append(s.charAt(i));for(int i = 0; i < n; i++)res.append(s.charAt(i));return res.toString();}
}

很明显上面两个都需要记住StringBuilder等的用法,如果使用最简单的String和char数组来处理怎么做呢?前面我们已经介绍过,所以这里只要看一下就明确了:

class Solution {public String reverseLeftWords(String s, int n) { if (s == null || s.length() == 0) {return s;}String res = "";for(int i = n; i < s.length(); i++)res += s.charAt(i);for(int i = 0; i < n; i++)res += s.charAt(i);return res;}
}

3.2 判定是否互为字符重排

给定两个字符串 s1s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例1:
输入 : s1 = “abcadfhg”, s2 = “bcafdagh” ’
输出 : true
示例2:
输入 : s1 = “abc”, s2 = “bad”
输出 : false

这个题第一眼看,感觉是个排列组合的题目,然后如果使用排列的算法来处理,难度会非常大,而且效果还不一定好。用简单的方式就能解决。

第一种方法:将两个字符串全部从小到大或者从大到小排列,然后再逐个位置比较,这时候不管两个原始字符串是什么,都可以判断出来。

代码也不复杂:

public boolean checkPermutation(String s1, String s2) { // 将字符串转换成字符数组char[] s1Chars = s1.toCharArray(); char[] s2Chars = s2.toCharArray();// 对字符数组进行排序Arrays.sort(s1Chars); Arrays.sort(s2Chars);// 再将字符数组转换成字符串,比较是否相等return new String(s1Chars).equals(new String(s2Chars));
}

注意这里我们使用了Arrays.sort(),你是否记得我们在数组一章提到过这个方法必须牢记。

第二种方法:使用Hash,注意这里我们不能简单的存是否已经存在,因为字符可能在某个串里重复存在例如"abac"。我们可以记录出现的次数,如果一个字符串经过重新排列后,能够变成另外一个字符串,那么它们的每个不同字符的出现次数是相同的。如果出现次数不同,那么表示两个字符串不能够经过重新排列得到。

这个代码逻辑不复杂,但是写起来稍微长一点:

class Solution {public boolean checkPermutation(String s1, String s2) {if (s1.length() != s2.length()) {return false;}char[] s1Chars = s1.toCharArray();Map<Character, Integer> s1Map = getMap(s1);Map<Character, Integer> s2Map = getMap(s2);for (char s1Char : s1Chars) {if (!s2Map.containsKey(s1Char) || s2Map.get(s1Char) != s1Map.get(s1Char)) {return false;}}return true;}// 统计指定字符串str中各字符的出现次数,并以Map的形式返回private Map<Character, Integer> getMap(String str) {Map<Character, Integer> map = new HashMap<>();char[] chars = str.toCharArray();for (char aChar : chars) {map.put(aChar, map.getOrDefault(aChar, 0) + 1);}return map;}
}

拓展

这个题还有一种方法,就是不管原始字符串有多长,是什么,基本元素都是26个英文字母,只少不多,那么我们可以换个思维:为两个字符串分别建立两个大小为26的字母表数组,每个位置是对应的字母出现的次数。最后统计一下两个数组的字母数和每个字母出现的次数就可以了。

这种方法其实也是文本搜索引擎的基本思想,例如 elasticSearch等,在文本搜索里有个专门的名字,叫“倒排索引”。看一下实现代码:

public class Solution {public boolean CheckPermutation(String s1, String s2) {if (s1.length() != s2.length()) {return false;}int[] c1 = count(s1);int[] c2 = count(s2);for (int i = 0; i < c1.length; i++) {if (c1[i] != c2[i]) {return false;}}return true;}private int[] count(String str) {int[] c = new int[26];char[] chars = str.toCharArray();for (char aChar : chars) {c[aChar - 'a']++;}return c;}
}

4. 最长公共前缀

这是一道经典的字符串问题,先看题目要求:

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

示例1:
输入:strs = [“flower”,“flow”,“flight”]
输出: “fl”
示例2:
输入:strs = [“dog”,“racecar”,“car”]
输出: “”
解释:输入不存在公共前缀。

要解答这个问题,我们需要先看一下公共前缀的分布有什么特点,如下图:
在这里插入图片描述
可以看到,第一种方式,我们可以竖着比较,如左图所示,每前进一个位置就比较各个串,看是不是都是相等的,只要在某一轮遇到一个不相等的,那么就结束。

第二种方式,还可以横着比较,先比较前两个找到公共前缀fix1,然后再和第三个比较公共前缀得到fix2,我们可以确定fix2一定不会比fix1更长,然后和第四个比较,得到fix4,一直到最后一个fixn。每次得到的fix都不会比前面的长,最后比较完了还剩下的就是需要找的前缀了。

看到这里你是否有种似曾相识的感觉,我们前面合并K个数组或者K个链表不也是类似的思路吗?是的,就是类似的思路。

第三种方式,我们是否可以对第二种进行优化一下,借鉴归并的思想,先两两一组找fix,然后将找到的fix再两两归并呢?当然可以了,这就是归并的方式。

先看第一种的实现方法,竖着比较。纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。

class Solution {public String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) {return "";}int length = strs[0].length();int count = strs.length;for (int i = 0; i < length; i++) {char c = strs[0].charAt(i);for (int j = 1; j < count; j++) {if (i == strs[j].length() || strs[j].charAt(i) != c) {return strs[0].substring(0, i);}}}return strs[0];}
}

第二种是横着依次比较,依次遍历字符串数组中的每个字符串,对于每个遍历到的字符串,更新最长公共前缀(其实就是看是否要缩短,一定不会变长),当遍历完所有的字符串以后,即可得到字符串数组中的最长公共前缀。

如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。

class Solution {public String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) {return "";}String prefix = strs[0];int count = strs.length;for (int i = 1; i < count; i++) {prefix = longestCommonPrefix(prefix, strs[i]);if (prefix.length() == 0) {break;}}return prefix;}public String longestCommonPrefix(String str1, String str2) {int length = Math.min(str1.length(), str2.length());int index = 0;while (index < length && str1.charAt(index) == str2.charAt(index)) {index++;}return str1.substring(0, index);}
}

再看第三种,归并方法,这种方式也可以叫分治,就是先两两判断,之后再两两比较,直到得到最终的结果。

class Solution {public String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) {return "";} else {return longestCommonPrefix(strs, 0, strs.length - 1);}}public String longestCommonPrefix(String[] strs, int start, int end) {if (start == end) {return strs[start];} else {int mid = (end - start) / 2 + start;String lcpLeft = longestCommonPrefix(strs, start, mid);String lcpRight = longestCommonPrefix(strs, mid + 1, end);return commonPrefix(lcpLeft, lcpRight);}}public String commonPrefix(String lcpLeft, String lcpRight) {int minLength = Math.min(lcpLeft.length(), lcpRight.length());for (int i = 0; i < minLength; i++) {if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {return lcpLeft.substring(0, i);}}return lcpLeft.substring(0, minLength);}
}

5. 字符串压缩问题

这个题也是出现频率很高的题目,经常在面经中看到。实现起来略有难度,我们一起看一下。

题目要求

给你一个字符数组 chars ,请使用下述算法压缩:

从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 :

如果这一组长度为 1 ,则将字符追加到 s 中。
否则,需要向 s 追加字符,后跟这一组的长度。
压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 10 或 10 以上,则在 chars 数组中会被拆分为多个字符。

请在修改完输入数组后 ,返回该数组的新长度。

你必须设计并实现一个只使用常量额外空间的算法来解决此问题。

示例 1:
输入:chars = [“a”,“a”,“b”,“b”,“c”,“c”,“c”]
输出:返回 6 ,输入数组的前 6 个字符应该是:[“a”,“2”,“b”,“2”,“c”,“3”]
解释:“aa” 被 “a2” 替代。“bb” 被 “b2” 替代。“ccc” 被 “c3” 替代。
示例 2:
输入:chars = [“a”]
输出:返回 1 ,输入数组的前 1 个字符应该是:[“a”]
解释:唯一的组是“a”,它保持未压缩,因为它是一个字符。
示例 3:
输入:chars = [“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]
输出:返回 4 ,输入数组的前 4 个字符应该是:[“a”,“b”,“1”,“2”]。
解释:由于字符 “a” 不重复,所以不会被压缩。“bbbbbbbbbbbb” 被 “b12” 替代。

这个题貌似采用双指针策略来处理就行,但是再分析发现三个指针才够。

我们可以使用两个指针分别标志我们在字符串中读和写的位置,还要一个指针left用来标记重复字段的开始位置。read指针不断向前读取,每次当读指针read 移动到某一段连续相同子串的最右侧,我们就在写指针 write 处依次写入该子串对应的字符和子串长度即可。

当读指针read位于字符串的末尾,或读指针read指向的字符不同于下一个字符时,我们就认为读指针read 位于某一段连续相同子串的最右侧。该子串对应的字符即为读指针 read 指向的字符串。我们使用变量 left 记录该子串的最左侧的位置,这样子串长度即为 read-left+1。

这里还有一个问题,就是长度可能超过10,因此还要实现将数字转化为字符串写入到原字符串的功能。这里我们采用短除法将子串长度倒序写入原字符串中,然后再将其反转即可。

class Solution {public int compress(char[] chars) {int n = chars.length;int write = 0, left = 0;for (int read = 0; read < n; read++) {if (read == n - 1 || chars[read] != chars[read + 1]) {chars[write++] = chars[read];int num = read - left + 1;if (num > 1) {int anchor = write;while (num > 0) {chars[write++] = (char) (num % 10 + '0');num /= 10;}reverse(chars, anchor, write - 1);}left = read + 1;}}return write;}public void reverse(char[] chars, int left, int right) {while (left < right) {char temp = chars[left];chars[left] = chars[right];chars[right] = temp;left++;right--;}}
}

6. 总结

我们介绍了很多字符串的基本题目,这些题目在面试现场写代码时经常会遇到。可以看到这些题目的处理方式与数组问题一脉相承,在数组里经常用的双指针也可以使用。但是因为字符串本身的特殊性,又要做很多特殊的处理,例如空格等等。

另外很多字符串的问题必须先将字符串转换成数组才能处理,这需要我们对charAt()等方法非常熟悉才可以。很多人会在简历里写 “精通java基础开发”,但是如果String的用法都忘了,甚至现场问面试官官,你还觉得自己精通吗?

字符串有很多经典,但是比较难的题目,这个难在需要使用回溯、动态规划等方法来处理,此等问题更适合在高级算法中介绍。例如最长回文串和字符串匹配等等。我们在后续的动态规划再研究。

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

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

相关文章

肺结节检测系统源码分享

肺结节检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

uniapp uview扩展u-picker支持日历期间 年期间 月期间 时分期间组件

uniapp uview扩展u-picker支持日历期间 年期间 月期间 时分期间组件 日历期间、年期间、月期间及时分期间组件在不同的应用场景中发挥着重要的作用。这些组件通常用于表单、应用程序或网站中&#xff0c;以方便用户输入和选择特定的日期和时间范围。以下是这些组件的主要作用&a…

C++:日期类的实现

目录 一、前言 二、头文件 三、各个函数的实现 打印、检查日期及获取日期 、、-、-、 、<、<、>、>、 &#xff01; 日期-日期 >>、<< 一、前言 前面几篇讲了关于类和对象的一些知识&#xff0c;本篇就来实现一下前面用到的日期类。 二、头文…

TryHackMe 第3天 | Pre Security (中)

该学习路径讲解了网络安全入门的必备技术知识&#xff0c;比如计算机网络、网络协议、Linux命令、Windows设置等内容。上一篇中简短介绍了计算机网络相关的知识&#xff0c;本篇博客将记录 网络协议 部分。 How the web works? DNS in detail DNS (Domain name system&…

Java面试篇-AOP专题(什么是AOP、AOP的几个核心概念、AOP的常用场景、使用AOP记录操作日志、Spring中的事务是如何实现的)

文章目录 1. 什么是AOP2. AOP的几个核心概念3. AOP的常用场景4. 使用AOP记录操作日志4.1 准备工作4.1.1 引入Maven依赖4.1.2 UserController.java4.1.3 User.java4.1.4 UserService.java 4.2 具体实现&#xff08;以根据id查询用户信息为例&#xff09;4.2.1 定义切面类&#x…

SkyWalking 环境搭建部署

架构简介 skywalking agent : 和业务系统绑定在一起,负责收集各种监控数据skywalking oapservice : 是负责处理监控数据的,比如接受skywalking agent的监控数据,并存储在数据库中;接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。Skywalking oapserv…

华为HarmonyOS地图服务 7- 在地图上绘制标记

场景介绍 本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。 点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、…

【RabbitMQ】消息分发、事务

消息分发 概念 RabbitMQ队列拥有多个消费者时&#xff0c;队列会把收到的消息分派给不同的消费者。每条消息只会发送给订阅该队列订阅列表里的一个消费者。这种方式非常适合扩展&#xff0c;如果现在负载加重&#xff0c;那么只需要创建更多的消费者来消费处理消息即可。 默…

linux网络编程5

24.9.21学习目录 一.TCP1.TCP流程2.TCP相关函数3.三次握手 一.TCP 1.TCP流程 服务器流程&#xff1a; 创建套接字socket&#xff08;&#xff09;将套接字与服务器网络信息结构体绑定bind&#xff08;&#xff09;将套接字设置为监听状态listen&#xff08;&#xff09;阻塞等…

进程间的通信4 共享内存

共享内存 1.共享内存简介 共享内存是将分配的物理空间直接映射到进程的用户虚拟地址空间中&#xff0c;减少数据在内核空间缓存共享内存是一种效率较高的进程间通讯的方式在 Linux 系统中通过 ipcs -m 查看所有的共享内存 共享内存模型图 2.共享内存的创建 1.函数头文件 #…

Java算法专栏

专栏导读 在当今这个技术日新月异的时代&#xff0c;Java算法作为软件开发的核心&#xff0c;对于提升程序性能和解决复杂问题至关重要。本“Java算法”专栏旨在帮助读者深入理解Java编程语言中的算法原理和应用&#xff0c;通过实战案例和深入分析&#xff0c;使读者能够掌握…

Java汽车销售管理

技术架构&#xff1a; springboot mybatis Mysql5.7 vue2 npm node 功能描述&#xff1a; 针对汽车销售提供客户信息、车辆信息、订单信息、销售人员管理、财务报表等功能&#xff0c;提供经理和销售两种角色进行管理 效果图&#xff1a;

Python基础学习(3)

目录 一&#xff0c;函数 1&#xff0c;函数的定义 2&#xff0c;函数的参数 1&#xff0c;默认值 2&#xff0c;传参 3&#xff0c;返回值 4&#xff0c;变量的作用域 5&#xff0c;函数的调用 二&#xff0c;常用数据结构 1&#xff0c;列表 列表的定义 列表的特性…

【Geoserver使用】REST API调用(工作空间部分)

文章目录 前言一、Geoserver REST API(GeoServer Workspace)二、GeoServer Workspace接口使用1.GET请求 /workspaces2.POST请求 /workspaces3.GET请求 /workspaces/{workspaceName}4.PUT /workspaces/{workspaceName}5.DELETE /workspaces/{workspaceName} 总结 前言 根据Geos…

C++ | Leetcode C++题解之第423题从英文中重建数字

题目&#xff1a; 题解&#xff1a; class Solution { public:string originalDigits(string s) {unordered_map<char, int> c;for (char ch: s) {c[ch];}vector<int> cnt(10);cnt[0] c[z];cnt[2] c[w];cnt[4] c[u];cnt[6] c[x];cnt[8] c[g];cnt[3] c[h] - …

YOLOv10 简介

YOLOv10&#xff0c;由清华大学的研究人员基于 Ultralytics Python 包构建&#xff0c;引入了一种全新的实时目标检测方法&#xff0c;该方法解决了以往 YOLO 版本中后处理和模型架构方面的不足。通过消除非极大值抑制&#xff08;NMS&#xff09;并优化各种模型组件&#xff0…

【解决】chrome 谷歌浏览器,鼠标点击任何区域都是 Input 输入框的状态,能看到输入的光标

chrome 谷歌浏览器&#xff0c;鼠标点击任何区域都是 Input 输入框的状态&#xff0c;能看到输入的光标 今天打开电脑的时候&#xff0c;网页中任何文本的地方&#xff0c;只要鼠标点击&#xff0c;就会出现一个输入的光标&#xff0c;无论在哪个站点哪个页面都是如此。 我知道…

十四、运算放大电路

运算放大电路 1、理想运算放大器的概念。运放的输入端虚拟短路、虚拟断路之间的区别; 2、反相输入方式的运放电路的主要用途&#xff0c;以及输入电压与输出电压信号的相位 3、同相输入方式下的增益表达式(输入阻抗、输出阻抗)

Redis-01 入门和十大数据类型

Redis支持两种持久化方式&#xff1a;RDB持久化和AOF持久化。 1.RDB持久化是将Redis的数据以快照的形式保存在磁盘上&#xff0c;可以手动触发或通过配置文件设置定时触发。RDB保存的是Redis在某个时间点上的数据快照&#xff0c;可以通过恢复RDB文件来恢复数据。 2.AOF持久化…

55. QTableWidget的基本使用

1. 说明 在软件界面开发中,基本上离不开数据的展示以供客户查看一些比较关注的信息,比如公司做一个员工个人信息管理系统,需要一个界面能够展示员工个人基本信息,实现这种效果可以采用多种形式,其中比较简单的一种是使用QT提供的QTableWidget控件,这个控件已经封装了一些…