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

news2024/11/17 17:39:55

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇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的最长公共子序列是dp
        String[][] 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.coloradmin.cn/o/984277.html

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

相关文章

Promise异步请求/async-await

问题&#xff1a;调接口时&#xff0c;非以往的函数异步请求去调接口。而是用到了Promise中.then方法 Promise Promise是一种用于处理异步操作的对象。它代表了一个尚未完成但预计会未来完成的操作&#xff0c;并提供了一种结构化的方式来处理操作的结果。它起到代理作用&…

合宙Air724UG LuatOS-Air LVGL API控件-键盘 (Keyboard)

键盘 (Keyboard) LVGL 可以添加触摸键盘&#xff0c;但是很明显&#xff0c;使用触摸键盘的话必须要使用触摸的输入方式&#xff0c;否则无法驱动键盘。 示例代码 function keyCb(obj, e)-- 默认处理事件lvgl.keyboard_def_event_cb(keyBoard, e)if(e lvgl.EVENT_CANCEL)the…

后流量时代的跨境风口:Facebook广告

Facebook拥有超过25亿各个年龄段和人群的每月活跃用户&#xff0c;可以帮助您接触世界各地的相关消费者。无论您是需要吸引新的潜在客户还是吸引回头客访问您的在线商店&#xff0c;Facebook广告都可以为电子商务提供丰厚的投资回报&#xff1b;无论您是在沃尔玛、eBay、亚马逊…

Spring-MVC的crud增删改查--详细讲解

目录 一.前言 二.crud---配置文件 2.1 pom.xml文件 2.2 web.xml文件 2.3 spring-context.xml 2.4 spring-mvc.xml 2.5 spring-MyBatis.xml 2.6 jdbc.properties数据库配置文件 2.7 generatorConfig.xml 2.8 日志文件log4j 三.后台 3.1 pageBean.java 3.2 pageTag 3.…

进军公有云这一年,OceanBase做了什么

*本文转载自微信公众号“机器之心&#xff0c;ID&#xff1a;almosthuman2014” 如今&#xff0c;数据库市场正在迈入新的竞争阶段——一场云上的角逐。 2022 年&#xff0c;中国公有云数据库市场规模首次过半[1]&#xff0c;预计未来占比将进一步扩大。许多中国的数据库厂商也…

新能源商用车软件开发设计规范

目 录 前 言.............................................................................................................. 1 1 范围............................................................................................................... 2 2 规范性…

用HexView 观察编译后的机器代码

HexView 用于打开任意一个文件&#xff0c;以十六进制的形式从头到尾显示它每个字节的内容。 下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1zB9r5WwuTMIPNMlYl5HlvA 提取码&#xff1a;5ndl双击启动 HexView&#xff0c;然后选择菜单“文件”-“打开文件以显…

专业游戏翻译公司怎么选择比较合适

近年来&#xff0c;游戏行业持续繁荣&#xff0c;市场需求也在不断扩大&#xff0c;其中游戏翻译的需求越来越旺盛。无论是引进游戏还是让游戏走向国际市场&#xff0c;都需要专业的翻译公司来帮忙。那么&#xff0c;怎么选择合适的游戏翻译公司呢&#xff1f;让我们一起来看看…

jmeter 准确的吞吐量定时器 Precise Throughput Timer

准确的吞吐量定时器使用实例 提取码&#xff1a;gpex&#xff1a; 说明&#xff1a;配置10个线程&#xff0c;每个线程请求200次&#xff0c;通过准确地屯托梁定时器模拟QPS为20的场景 配置测试接口参考链接 配置jmeter测试脚本&#xff0c;主要关注准确的吞吐量定时器参数配置…

(2022 COLING)Context-Tuning情景化提示

论文题目&#xff08;Title&#xff09;&#xff1a;Context-Tuning: Learning Contextualized Prompts for Natural Language Generation 研究问题&#xff08;Question&#xff09;&#xff1a;自然语言生成&#xff0c;生成长文本。 研究动机&#xff08;Motivation&#…

春播秋收 “羊”鸣德州 一场“苏尼特羊”跨越千里的美丽邂逅

恰逢金秋丰收时节&#xff0c;中秋佳节来临之际&#xff0c;9月2日&#xff0c;百仕达地标之都整合天南海北优质农产品&#xff0c;联合苏尼特右旗和德州市天衢新区&#xff0c;共同举办“2023年地标之都中秋选货节暨苏尼特羊推介会”。 本次活动以“ 收自然之硕鉴本味之美”为…

国标GB28181协议视频平台EasyGBS国标平台设备播放断流现象的排查分析及解决

EasyGBS平台基于GB28181国标协议&#xff0c;支持多路设备接入&#xff0c;并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等多种格式的视频流。平台可为大数据等综合性监管平台提供极强的视频能力&#xff0c;已经在大量的项目中落地应用&#xff0c;如明厨亮灶、平安…

框架分析(10)-SQLAlchemy

框架分析&#xff08;10&#xff09;-SQLAlchemy 专栏介绍SQLAlchemy特性分析ORM支持数据库适配器事务支持查询构建器数据库连接池事务管理器数据库迁移特性总结 优缺点优点强大的对象关系映射支持多种数据库灵活的查询语言自动管理数据库连接支持事务管理易于扩展和定制 缺点学…

华硕ROG2/ROG5/ROG6/ROG7Pro强解锁L锁-快速实现root权限-支持Zenfone9/8/7

2023年9月新增解锁BL适配&#xff08;需要联系技术远程操作&#xff09;&#xff1a; 新增支持华硕ROG5/5S/5Pro机型强制解锁BL&#xff0c;并且支持OTA在线更新功能 新增支持华硕ROG6/6Pro机型强制解锁BL&#xff0c;并且支持OTA在线更新功能 新增支持华硕ROG7/7Pro机型强制解…

antd中在vue项目中自定义穿梭框

antd中在vue项目中自定义穿梭框 1、完成代码 <template><a-modaltitle"高危因素选择":width"1000":visible"riskVisible":confirm-loading"confirmLoading"ok"handleOk"cancel"handleCancel"okText&qu…

攻克海外市场!企业客户培育,销售额倍增

随着全球市场的不断融合和国际贸易的加速&#xff0c;越来越多的企业纷纷进军海外市场&#xff0c;寻求新的增长机会。然而&#xff0c;在这一过程中&#xff0c;客户培育成为了取得成功的关键因素之一。运营坛今天将带领大家深入剖析为什么客户培育在国际市场尤为关键&#xf…

手写Spring:第2章-创建简单的Bean容器

文章目录 一、目标&#xff1a;创建简单的Bean容器二、设计&#xff1a;创建简单的Bean容器三、实现&#xff1a;创建简单的Bean容器3.0 引入依赖3.1 工程结构3.2 创建简单Bean容器类图3.3 Bean定义3.4 Bean工厂 四、测试&#xff1a;创建简单的Bean容器4.1 用户Bean对象4.2 单…

cmake编译(qtcreator)mingw下使用的osg3.6.5

官网下载osg3.6.5源码&#xff0c;先不使用依赖库&#xff0c;直接进行编译 如果generate后报错&#xff0c;显示找不到boost必须库&#xff0c;则手动增加路径。然后先在命令行中使用mingw32-make&#xff0c;如果显示不存在&#xff0c;则需要去环境变量里配置一下这个工具的…

h5开发网站-使用jquery来实现二层嵌套的左侧列表,点击后显示右侧内容的效果

一、需求&#xff1a; 使用jquery来实现二层嵌套的左侧列表&#xff0c;点击后显示右侧内容的效果。 二、思路&#xff1a; 为一级列表项和二级子列表项分别添加了点击事件处理程序。当一级列表项被点击时&#xff0c;使用.slideToggle()方法展开或收起对应的二级子列表项。…

Linux--进程--vfork与fork区别

vfork&#xff1a; 所需头文件&#xff1a;#include <sys/types.h> #include <unistd.h> pid_t vfork(void); 功能&#xff1a; vfork() 函数和 fork() 函数一样都是在已有的进程中创建一个新的进程&#xff0c;但它们创建的子进程是有区别的。 参数&#xff…