【算法训练-字符串 三】最长公共子串、最长公共子序列

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【】,使用【】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

在这里插入图片描述

名曲目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

最长公共子串【MID】

首先来一道最长公共子串,难度还没有升级,公共字符是连续的即可

题干

直接粘题干和用例

解题思路

求两个数组或者字符串的最长公共子序列问题,肯定是要用动态规划的。

  • 首先,区分两个概念:子序列可以是不连续的子数组(子字符串)需要是连续的
  • 另外,单个数组或者字符串要用动态规划时,可以把动态规划 dp[i] 定义为 nums[0:i] 中想要求的结果;当两个数组或者字符串要用动态规划时,可以把动态规划定义成两维的 dp[i][j] ,其含义是在 A[0:i]B[0:j] 之间匹配得到的想要的结果。

1. 状态定义

对于本题而言,可以定义 dp[i][j] 表示 text1[0:i-1]text2[0:j-1] 的最长公共子序列。 (注:text1[0:i-1] 表示的是 text1 的 第 0 个元素到第 i - 1 个元素,两端都包含) 之所以 dp[i][j] 的定义不是 text1[0:i]text[0:j] ,是为了方便当 i = 0 或者 j = 0 的时候,dp[i][j]表示空字符串和另外一个字符串的匹配,这样 dp[i][j] 可以初始化为空字符串

2. 状态转移方程

知道状态定义之后,开始写状态转移方程。

  • text1[i - 1] == text2[j - 1] 时,说明两个子字符串的最后一位相等,所以最长公共子串长度又增加了 1,所以 dp[i][j] = dp[i - 1][j - 1] + text1[i]
  • text1[i - 1] != text2[j - 1] 时,说明两个子字符串的最后一位不相等,所以不够成公共子串,不满足条件

综上状态转移方程为:

  • dp[i][j] = dp[i - 1][j - 1] + s1.charAt(i - 1), 当 text1[i−1]==text2[j−1]

当然我们还需要当前最新下标来辅助记录子串最新的更新位置

3. 状态的初始化

初始化就是要看当 i = 0 与 j = 0 时, dp[i][j] 应该取值为多少。

  • 当 i = 0 时,dp[0][j] 表示的是 text1中取空字符串 跟 text2的最长公共子序列,结果肯定为 空字符串.
  • 当 j = 0 时,dp[i][0] 表示的是 text2中取空字符串 跟 text1的最长公共子序列,结果肯定为 空字符串.

综上,当 i = 0 或者 j = 0 时,dp[i][j] 初始化为 空字符串.

4. 遍历方向与范围

由于 dp[i][j] 依赖于 dp[i - 1][j - 1] ,,所以 i和 j的遍历顺序肯定是从小到大(自底向上)的。 另外,由于当 i和 j 取值为 0 的时候,dp[i][j] = 0,而 dp 数组本身初始化就是为 空字符串,所以,直接让 i 和 j 从 1 开始遍历。遍历的结束应该是字符串的长度为 len(text1)len(text2)

5. 最终返回结果

由于 dp[i][j] 的含义是 text1[0:i-1]text2[0:j-1] 的最长公共子序列。我们最终希望求的是 text1 和 text2 的最长公共子序列。所以需要返回的结果是 i = len(text1) 并且 j = len(text2) 时的 dp[len(text1)][len(text2)]

代码实现

给出代码实现基本档案

基本数据结构字符串
辅助数据结构
算法动态规划
技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** longest common substring* @param str1 string字符串 the string* @param str2 string字符串 the string* @return string字符串*/public String LCS (String str1, String str2) {// 入参条件判断if (str1 == null || str1.length() == 0 || str2 == null || str2.length() == 1) {return null;}// 1 初始化状态int ls1 = str1.length();int ls2 = str2.length();// dp表示范围为0-ls1的str1与0-ls2的str2的最长公共子串长度int[][] dp = new int[ls1 + 1][ls2 + 1];int max = 0;int latestIndex = 0;// 2 遍历(自底向上)for (int i = 1; i <= ls1; i++) {for (int j = 1; j <= ls2; j++) {// 状态转移方程if (str1.charAt(i - 1) == str2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;// 更新子串最大长度以及当前子串下标if (dp[i][j] > max) {max = dp[i][j];// 公共子串不包含latestIndex位置latestIndex = i;}}}}// 上述循环i从1开始,这里subString右侧为开区间,刚好适用return str1.substring(latestIndex - max, latestIndex);}
}

复杂度分析

时间复杂度:O(n^2 ),构造辅助数组dp与b,两层循环,递归是有方向的递归,因此只是相当于遍历了二维数组
空间复杂度:O(n^2 ),辅助二维数组dp与递归栈的空间最大为O(n^2 )

最长公共子序列【MID】

难度升级,明确下什么是公共子序列。一个字符串的子序列是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串

例如,aceabcde的子序列,但 aec不是 abcde 的子序列

题干

直接粘题干和用例

解题思路

求两个数组或者字符串的最长公共子序列问题,肯定是要用动态规划的。

  • 首先,区分两个概念:子序列可以是不连续的子数组(子字符串)需要是连续的
  • 另外,单个数组或者字符串要用动态规划时,可以把动态规划 dp[i] 定义为 nums[0:i] 中想要求的结果;当两个数组或者字符串要用动态规划时,可以把动态规划定义成两维的 dp[i][j] ,其含义是在 A[0:i]B[0:j] 之间匹配得到的想要的结果。

在这里插入图片描述

1. 状态定义

对于本题而言,可以定义 dp[i][j] 表示 text1[0:i-1]text2[0:j-1] 的最长公共子序列。 (注:text1[0:i-1] 表示的是 text1 的 第 0 个元素到第 i - 1 个元素,两端都包含) 之所以 dp[i][j] 的定义不是 text1[0:i]text[0:j] ,是为了方便当 i = 0 或者 j = 0 的时候,dp[i][j]表示空字符串和另外一个字符串的匹配,这样 dp[i][j] 可以初始化为空字符串

2. 状态转移方程

知道状态定义之后,开始写状态转移方程。

  • text1[i - 1] == text2[j - 1] 时,说明两个子字符串的最后一位相等,所以最长公共子序列又增加了 1,所以 dp[i][j] = dp[i - 1][j - 1] + text1[i];举个例子,比如对于 ac 和 bc 而言,他们的最长公共子序列的长度等于 a 和 b 的最长公共子序列长度 0 + text[1] = c。
  • text1[i - 1] != text2[j - 1] 时,说明两个子字符串的最后一位不相等,那么此时的状态 dp[i][j] 应该是 dp[i - 1][j]dp[i][j - 1] 的最大值。举个例子,比如对于 ace 和 bc 而言,他们的最长公共子序列等于 ① ace 和 b 的最长公共子序列:空字符串的长度0 与 ② ac 和 bc 的最长公共子序列c长度1 的最大值,即 1,所以选择长度大的

综上状态转移方程为:

  • dp[i][j] = dp[i - 1][j - 1] + s1.charAt(i - 1), 当 text1[i−1]==text2[j−1]
  • dp[i][j] = dp[i - 1][j].length() > dp[i][j - 1].length() ? dp[i - 1][j] : dp[i][j - 1];, 当 text1[i−1]!=text2[j−1]

3. 状态的初始化

初始化就是要看当 i = 0 与 j = 0 时, dp[i][j] 应该取值为多少。

  • 当 i = 0 时,dp[0][j] 表示的是 text1中取空字符串 跟 text2的最长公共子序列,结果肯定为 空字符串.
  • 当 j = 0 时,dp[i][0] 表示的是 text2中取空字符串 跟 text1的最长公共子序列,结果肯定为 空字符串.

综上,当 i = 0 或者 j = 0 时,dp[i][j] 初始化为 空字符串.

4. 遍历方向与范围

由于 dp[i][j] 依赖于 dp[i - 1][j - 1] ,,所以 i和 j的遍历顺序肯定是从小到大(自底向上)的。 另外,由于当 i和 j 取值为 0 的时候,dp[i][j] = 0,而 dp 数组本身初始化就是为 空字符串,所以,直接让 i 和 j 从 1 开始遍历。遍历的结束应该是字符串的长度为 len(text1)len(text2)

5. 最终返回结果

由于 dp[i][j] 的含义是 text1[0:i-1]text2[0:j-1] 的最长公共子序列。我们最终希望求的是 text1 和 text2 的最长公共子序列。所以需要返回的结果是 i = len(text1) 并且 j = len(text2) 时的 dp[len(text1)][len(text2)]

代码实现

给出代码实现基本档案

基本数据结构字符串
辅助数据结构
算法动态规划
技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** longest common subsequence* @param s1 string字符串 the string* @param s2 string字符串 the string* @return string字符串*/public String LCS (String s1, String s2) {// 0 入参校验if (s1 == null || s1.length() == 0 || s2 == null ||s2.length() == 0) return "-1";// 1 状态定义及初始化int ls1 = s1.length();int ls2 = s2.length();// 长度为ls1和长度为ls2的最长公共子序列是dpString[][] dp = new String[ls1 + 1][ls2 + 1];// 2 初始化状态值,当初始化状态时,公共子序列为空字符串for (int i = 0; i <= ls1; i++) {// j为0表示一个长度不为0的s1和一个长度永远为0的字符串公共子序列一定是空字符串dp[i][0] = "";}for (int j = 0; j <= ls2; j++) {// i为0表示一个长度不为0的s1和一个长度永远为0的字符串公共子序列一定是空字符串dp[0][j] = "";}// 3 自底向上遍历for (int i = 1; i <= ls1; i++) {for (int j = 1; j <= ls2; j++) {// 4 状态转移方程if (s1.charAt(i - 1) == s2.charAt(j - 1)) {// 如果s1和s2的字符相等,dp[1][1]表示dp[0][0]+a=a(自底向上)dp[i][j] = dp[i - 1][j - 1] + s1.charAt(i - 1);} else {// 如果s1和s2的字符不相等,取dp[i - 1][j]和dp[i][j - 1]较长的字符作为dp[i][j]dp[i][j] = dp[i - 1][j].length() > dp[i][j - 1].length() ? dp[i - 1][j] :dp[i][j - 1];}}}// 5 返回的是两个完整s1和s2的公共子序列return dp[ls1][ls2] == "" ? "-1" : dp[ls1][ls2];}
}

复杂度分析

时间复杂度:O(n^2 ),构造辅助数组dp与b,两层循环,递归是有方向的递归,因此只是相当于遍历了二维数组
空间复杂度:O(n^2 ),辅助二维数组dp与递归栈的空间最大为O(n^2 )

拓展知识:动态规划

动态规划基本概念

动态规划(Dynamic Programming,简称DP)算法是一种解决复杂问题的算法设计和优化技术,常用于解决具有重叠子问题性质和最优子结构性质的问题。它的核心思想是将一个大问题分解成一系列相互重叠的子问题,然后将子问题的解存储起来,以避免重复计算,从而节省时间

动态规划算法通常包括以下关键步骤:

  1. 定义子问题:将原问题分解成若干个子问题,并明确定义每个子问题的输入和输出。

  2. 构建状态转移方程:确定每个子问题与其他子问题之间的关系,即如何通过已解决的子问题来解决当前子问题。这通常通过递归或迭代方式建立状态转移方程。

  3. 初始化:初始化基本情况,通常是问题规模较小或无法再分时的边界情况。

  4. 自底向上求解或使用备忘录法:根据状态转移方程,从最小的子问题开始解决,逐步构建出更大规模的问题的解。可以使用自底向上的迭代方法或备忘录法来避免重复计算。

  5. 返回结果:根据状态转移方程求解出原问题的解。

动态规划广泛应用于各种领域,包括算法设计、优化问题、路径规划、序列比对、字符串处理、游戏策略等。经典的动态规划问题包括斐波那契数列、背包问题、最长公共子序列、最短路径问题

动态规划的优点是可以显著减少重复计算,提高效率,但其缺点是需要合理定义子问题和状态转移方程,有时需要额外的内存空间来存储中间结果。因此,在解决问题时,需要仔细分析问题的性质,确定是否适合使用动态规划算法。

动态规划、递归、分治的区别

下面是动态规划、递归和分治这三种算法的相同点和不同点的表格展示:

特点动态规划递归分治
求解方式自底向上自顶向下分而治之
重复计算处理避免重复计算,通过存储子问题的解来提高效率可能重复计算相同的子问题分解问题并独立处理子问题
时间复杂度通常具有较低的时间复杂度可能具有较高的时间复杂度通常具有中等的时间复杂度
适用性适用于具有重叠子问题性质和最优子结构性质的问题适用于结构天然呈递归性质的问题适用于问题可以分解为独立的子问题
经典问题举例背包问题、最短路径问题、斐波那契数列树形结构的问题、图遍历快速排序、归并排序
记忆化/缓存通过存储中间结果,具有记忆化的特点可以使用记忆化技巧来减少重复计算分治通常不涉及记忆化
稳定性具有稳定性,不受输入数据顺序影响可能受输入数据顺序影响通常具有稳定性,不受输入数据顺序影响

这个表格概括了动态规划、递归和分治算法之间的一些主要相同点和不同点。需要注意的是,这些算法的选择取决于具体问题的性质和要求,有时候也可以根据问题的特点将它们结合使用,以获得更好的性能和效果。

高频算法题归类

适用于这些算法思想的题目

动态规划处理的高频算法题

动态规划是一个非常强大的算法技巧,适用于解决各种高频的算法问题。以下是一些使用动态规划解决的常见高频算法题目:

  1. 斐波那契数列问题:计算斐波那契数列的第n个数,可以使用动态规划来避免指数级的重复计算。

  2. 背包问题:如 0-1 背包问题、完全背包问题、多重背包问题等,动态规划可用于优化资源分配问题。

  3. 最长公共子序列问题:寻找两个字符串的最长公共子序列,动态规划可用于解决字符串匹配和相似性比较问题。

  4. 最长递增子序列问题:寻找一个数组中最长的递增子序列,常用于优化问题和排序问题。

  5. 最短路径问题:如 Dijkstra 算法、Floyd-Warshall 算法,用于在图中找到最短路径或最短距离。

6. 编辑距离问题:计算两个字符串之间的最小编辑操作数,如插入、删除和替换操作。

7. 股票买卖问题:寻找股票价格数组中的最佳买卖时机,以获得最大的利润。

  1. 子集和问题:确定给定集合中是否存在一个子集,其元素之和等于特定目标值。

  2. 矩阵链乘法问题:在给定一组矩阵的情况下,确定它们相乘的最佳顺序以最小化乘法运算的次数。

  3. 字符串匹配问题:如正则表达式匹配、通配符匹配等,用于模式匹配和文本搜索。

这些问题只是动态规划可以解决的众多示例之一。动态规划的思想可以应用于各种优化和最优化问题,它的关键是将问题分解成子问题并找到适当的状态转移规则。因此,当你面对一个复杂的问题时,考虑是否可以使用动态规划来提高问题求解的效率和准确性。

分治算法处理的高频算法题

分治算法是一种重要的算法技巧,适用于解决各种高频的算法问题,特别是分而治之的思想。以下是一些使用分治算法解决的常见高频算法题目:

  1. 归并排序:分治算法的经典示例之一,用于将一个大数组分割成较小的子数组,排序子数组,然后将它们合并以得到有序数组。

  2. 快速排序:另一种基于分治思想的排序算法,通过选择一个基准元素,将数组划分成两个子数组,然后递归地对子数组进行排序。

  3. 连续子数组的最大和:给定一个整数数组,查找具有最大和的连续子数组。分治算法可以用于高效解决这个问题。

  4. 求解最近点对问题:给定一个包含多个点的平面,找到最接近的一对点。该问题可以通过分治算法以较低的时间复杂度解决。

  5. 矩阵乘法:分治算法可以用于将矩阵分割成子矩阵,然后递归地进行矩阵乘法操作,以减少计算次数。

  6. 大整数乘法:用于计算两个大整数的乘积,分治算法可以用于将大整数分解为较小的整数,并递归地计算它们的乘积。

  7. 众数问题:查找数组中出现次数超过一半的元素,分治算法可以在线性时间内解决这个问题。

  8. 合并K个有序链表:将K个有序链表合并为一个有序链表,分治算法可以用于高效解决这个问题。

  9. 寻找第K大/小的元素:在一个未排序的数组中找到第K大或第K小的元素,分治算法可以用于解决这个问题。

  10. 求解凸多边形的最小包围矩形:给定一个凸多边形,找到包围它的最小矩形。分治算法可用于高效计算最小包围矩形。

这些问题只是分治算法可以解决的众多示例之一。分治算法的关键思想是将问题分解为相互独立的子问题,然后将子问题的解合并以得到原问题的解。当你面对一个需要分而治之的问题时,考虑是否可以使用分治算法来提高问题求解的效率和准确性。

递归算法处理的高频算法题

递归算法是一种常见且强大的算法技巧,适用于解决各种高频的算法问题。以下是一些使用递归算法解决的常见高频算法题目:

  1. 二叉树遍历:包括前序遍历、中序遍历、后序遍历等,用于访问和处理二叉树的节点。

  2. 分解问题:许多问题可以通过将它们分解为更小的相似子问题来解决,例如斐波那契数列、汉诺塔问题等。

  3. 递归的数据结构:如链表、树、图等数据结构的处理通常使用递归来实现。

  4. 组合和排列问题:生成所有可能的组合或排列,如子集生成、排列生成等。

  5. 回溯算法:解决一些组合优化问题,如八皇后问题、数独问题等。

  6. 图的遍历:深度优先搜索(DFS)和广度优先搜索(BFS)是递归的常见应用,用于解决图相关的问题。

  7. 递归的搜索和查找:二分查找、树的搜索、图的最短路径等问题可以使用递归算法解决。

  8. 分治算法:分治算法的核心思想就是递归,如归并排序、快速排序等。

  9. 递归背包问题:解决背包问题的变种,如动态规划中的背包问题。

  10. 字符串处理:字符串匹配、编辑距离、正则表达式匹配等问题通常可以使用递归来解决。

这些问题只是递归算法可以解决的众多示例之一。递归算法的关键思想是将问题分解为更小的相似问题,并通过递归调用自身来解决这些子问题。当你面对一个需要不断分解问题的情况时,考虑是否可以使用递归来解决,但需要小心避免无限递归,确保有适当的终止条件。

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

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

相关文章

使用多线程或异步技术提高图片抓取效率

导语 图片抓取是爬虫技术中常见的需求&#xff0c;但是图片抓取的效率受到很多因素的影响&#xff0c;比如网速、网站反爬机制、图片数量和大小等。本文将介绍如何使用多线程或异步技术来提高图片抓取的效率&#xff0c;以及如何使用爬虫代理IP来避免被网站封禁。 概述 多线…

C++多态案例-设计计算器类

1.前置知识点 多态是面向对象的三大特性之一 多态分为两类 静态多态&#xff1a;函数重载和运算符重载都属于静态多态&#xff0c;复用函数名动态多态&#xff1a;派生类和虚函数实现运行时多态 静态多态和动态多态的区别 静态多态的函数地址早绑定-----编译阶段确定函数地…

Ukey连接虚拟前置机,浦银安盛基金用USB Server解决

浦银安盛基金一直使用物理前置机来连接Ukey&#xff0c;物理前置机维护管理不便&#xff0c;严重影响金融交易效率。因此&#xff0c;浦银安盛基金想要推进企业虚拟化&#xff0c;通过在虚拟机中部署前置机程序的方式&#xff0c;将前置机部署到虚拟机中。但虚拟机中的前置机&a…

shell脚本指令:for循环、函数、数组、grep等指令的使用

1、实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 2、写一个函数&#xff0c;输出当前用户的uid和gid 并使用变量接收结果 #!/bin/bash echo "请输入一个数组" read -a arr function add_arr() {var1${#arr[*]}for i in ${arr[*]} do((sumi))doner…

微信小程序上拉触底事件

一、什么是上拉触底事件 上拉触底是移动端的专有名词&#xff0c;通过手指在屏幕上的上拉滑动操作&#xff0c;从而加载更多数据的行为。 二、监听上拉触底事件 在页面的.js文件中&#xff0c;通过onReachBottom()函数即可监听当前页面的上拉触底事件。 三、配置上拉触底距…

一生一芯10——verilator v5.008环境搭建

搜索 verilator 官网&#xff0c;得到网址如下&#xff1a; https://www.veripool.org/verilator/ 点击download 找到 git quick install 可以看到git快捷安装所需命令行 可以看到&#xff0c;需要预先安装下面的包文件&#xff0c;去掉前面的#注释符号进行安装 直接进行下面…

天津大数据培训学校 大数据可从事的行业

大数据行业近年来呈现出爆炸式的增长态势&#xff0c;各行各业都越来越依赖数据来指导业务决策和创新发展&#xff0c;因此&#xff0c;大数据专业人才的需求也随之增长。这种行业需求的增长为大数据就业提供了良好的机会&#xff0c;尤其是对于具备相关技能和知识的人来说。 …

【C#】关于Array.Copy 和 GC

关于Array.Copy 和 GC //一个简单的 数组copy 什么情况下会触发GC呢[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]public static void Copy(Array sourceArray,long sourceIndex,Array destinationArray,long destinationIndex,long length);当源和目…

173. 二叉搜索树迭代器

173. 二叉搜索树迭代器 题目-中等难度示例1. 列表解 题目-中等难度 实现一个二叉搜索树迭代器类BSTIterator &#xff0c;表示一个按中序遍历二叉搜索树&#xff08;BST&#xff09;的迭代器&#xff1a; BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的…

js如何实现字符串反转?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用 split() 和 reverse() 方法⭐ 使用循环⭐ 使用递归⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专…

肖sir__设计测试用例方法之因果图07_(黑盒测试)

设计测试用例方法之因果图 一、定义&#xff1a;因果图提供了一个把规格转化为判定表的系统化方法&#xff0c;从该图中可以产生测试数据。其 中&#xff0c;原因是表示输入条件&#xff0c;结果是对输入执 行的一系列计算后得到的输出。 二、因果图方法最终生成的就是判定表。…

MySQL主从复制读写分离

读写分离 读写分离&#xff0c;基本的原理是让主数据库处理事务性增、改、删操作&#xff08;INSERT、UPDATE、DELETE&#xff09;&#xff0c;而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库 读写分离的好处 因为数据库的“写…

【Linux基础】权限管理

​&#x1f47b;内容专栏&#xff1a; Linux操作系统基础 &#x1f428;本文概括&#xff1a; 用户之间的切换、sudo提权、Linux权限管理、文件访问权限的相关方法、目录权限、粘滞位等 &#x1f43c;本文作者&#xff1a; 阿四啊 &#x1f438;发布时间&#xff1a;2023.9.11 …

elasticsearch的DSL查询文档

DSL查询分类 查询所有&#xff1a;查询出所有数据&#xff0c;一般测试用。例如&#xff1a;match_all 全文检索&#xff08;full text&#xff09;查询&#xff1a;利用分词器对用户输入内容分词&#xff0c;然后去倒排索引库中匹配。例如&#xff1a; match_query multi_ma…

在Qt创建的UI中放一个显示点云的窗口(PCL+QT5)

1、首先在Qt Designer创建UI后&#xff0c;拖一个Widget窗口出来 2、在对象查看器中右击该Widget&#xff0c;选择提升窗口部件&#xff0c;如下操作&#xff1a; 3、把UI转出来放在VS项目中&#xff0c;其中你的UI代码头文件会自带QVTKOpenGLNativeWidget.h&#xff0c;当然你…

小谈设计模式(1)—总序

小谈设计模式&#xff08;1&#xff09;—总序 开始操作设计模式总论设计模式是什么组成要素模式名称问题描述解决方案效果描述 设计模式有什么作用提供可重用的解决方案提高代码的可读性和可维护性促进代码的可扩展性提高代码的灵活性和可重用性促进团队合作和沟通作用总结 为…

基于HBuilder X平台下的 驾校报名考试管理系统 uniapp 微信小程序3n9o5

本课题研究的是基于HBuilder X系统平台下的驾校管理系统&#xff0c;开发这款驾校管理系统主要是为了帮助学员可以不用约束时间与地点进行查看教练信息、考场信息等内容。本文详细讲述了驾校管理系统的界面设计及使用&#xff0c;主要包括界面的实现、控件的使用、界面的布局和…

【计算机网络】 TCP协议头相关知识点

文章目录 TCP协议头 TCP协议头 我们来看一下TCP协议头里都有什么东西&#xff0c;研究一下为什么TCP协议是可靠的呢 TCP协议可靠是因为在协议头里带着一些校验的数据 首先是源端口和目的端口&#xff0c;这两个是UDP中也有的&#xff0c;但是UDP中只有这两个&#xff0c;没有…

基于Linux的智能家居(工厂模式)

目录 1.项目概述 2.程序框架 3.函数准备 3.1需要函数知识点 3.2编码提醒 4.代码 5.注意事项 1.项目概述 控制端有两个&#xff0c;语音串口UART和Tcp通讯。 执行端有IO输出和IO输入。 2.程序框架 程序分为3部分-------------1.输入控制 2.输出设备 3.主函数-多线程…

文件上传漏洞案例

目录 1.案例一 1&#xff09;案例源码 2&#xff09;创建web.php文件 3&#xff09;使用抓包软件 2.案例二 1&#xff09;案例代码 2&#xff09; 案例分析 3&#xff09;copy命令生成图片马 4&#xff09;上传图片马到服务器 5&#xff09;解析 文件图片 3.案例三 …