【算法设计与分析】——动态规划算法

🎃个人专栏:

🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客

🐳Java基础:Java基础_IT闫的博客-CSDN博客

🐋c语言:c语言_IT闫的博客-CSDN博客

🐟MySQL:数据结构_IT闫的博客-CSDN博客

🐠数据结构:​​​​​​数据结构_IT闫的博客-CSDN博客

💎C++:C++_IT闫的博客-CSDN博客

🥽C51单片机:C51单片机(STC89C516)_IT闫的博客-CSDN博客

💻基于HTML5的网页设计及应用:基于HTML5的网页设计及应用_IT闫的博客-CSDN博客​​​​​​

🥏python:python_IT闫的博客-CSDN博客

🐠离散数学:离散数学_IT闫的博客-CSDN博客

欢迎收看,希望对大家有用!

目录

🎯内容概括:

🎯目的:

🎯基本步骤:

🎯环境:

🎯内容:

💻one:

🎃问题:

🎃解题思路:

🎃代码分析:

🎃总代码:

🎃 运行截图:

 💻two:

🎃问题:

🎃解题思路:

🎃代码分析:

🎃总代码:

🎃运行截图:

 💻three:

🎃问题:

🎃解题思路:

🎃代码分析:

 🎃总代码:

🎯 做题方法总结:


🎯内容概括:

1)矩阵连乘问题:已知矩阵A1A2A3A4A5 ,使用向量P<P0=3,P1=2,P2=5,P3=10,P4=2,P5=3>存储行列,求出相乘次数最少的加括号位置。

2)0-1背包问题:有5个物品,其重量分别为{2,2,6,5,4},价值分别为{6,3,5,4,6}。背包容量为10,物品不可分割,求装入背包的物品和获得的最大价值。

3)最长公共子序列问题:求X={A,B,C,B,D,A,B}和Y={B,D,C,A,B,A}的最长公共子序列。

🎯目的:

1)了解动态规划算法思想;

2)掌握算法的基本要素及解题步骤;

3)能够对实际问题,能够按照动态规划解题步骤,分析问题;

4)能够正确的编码、实现动态规划算法;

5)能够正确分析算法的时间复杂度和空间复杂度。

🎯基本步骤:

1)审阅题目,明确题目的已知条件和求解的目标;

2)问题建模;

3)算法设计;

4)编码实现(语言不限);

5)测试数据;

6)程序运行结果;

7)分析实验结果是否符合预期,如果不符合,分析可能的原因;

8)算法分析。

🎯环境:

VC6.0 / Eclipse / Pycharm。

🎯内容:

💻one:

🎃问题:

1)矩阵连乘问题:已知矩阵A1A2A3A4A5 ,使用向量P<P0=3,P1=2,P2=5,P3=10,P4=2,P5=3>存储行列,求出相乘次数最少的加括号位置。

🎃解题思路:

  1. 创建两个二维数组m和s,其中m[i][j]表示从矩阵Ai到Aj的连乘所需的最少次数,s[i][j]表示从矩阵Ai到Aj的连乘的最优加括号位置。
  2. 初始化m[i][i]为0,表示单个矩阵相乘的次数为0。
  3. 对于长度l=2到n的子链长度,依次计算m[i][j]和s[i][j]
  • 遍历每个可能的分割点k,计算m[i][j]的值。
  • m[i][j]的值等于m[i][k] + m[k+1][j] + Pi-1 * Pk * Pj。
  • 更新m[i][j]时,同时更新s[i][j]为k,表示在Ai到Aj之间最优的加括号位置是在矩阵Ak与Ak+1之间。

     4.最终,m[1][n]存储的即为从A1到An连乘的最小次数。

🎃代码分析:

matrix1 方法:

public static void matrix1(int[] p) {int n = p.length - 1;int[][] x = new int[n][n];int[][] y = new int[n][n];for (int l = 2; l <= n; l++) {for (int i = 0; i < n - l + 1; i++) {int j = i + l - 1;x[i][j] = Integer.MAX_VALUE;for (int k = i; k < j; k++) {int q = x[i][k] + x[k + 1][j] + p[i] * p[k + 1] * p[j + 1];if (q < x[i][j]) {x[i][j] = q;y[i][j] = k;}}}}System.out.println("相乘次数最少的加括号的位置为:");print(y, 0, n - 1);System.out.println();System.out.println("最少相乘次数:" + x[0][n - 1]);
}

 这个方法使用动态规划来解决矩阵链乘问题。它通过填充二维数组 xy 来计算最少相乘次数和最优加括号位置。


print 方法:

public static void print(int[][] s, int i, int j) {if (i == j) {System.out.print("A" + (i + 1));} else {System.out.print("(");print(s, i, s[i][j]);print(s, s[i][j] + 1, j);System.out.print(")");}
}

这个方法用于打印最优加括号位置。根据数组 s 中存储的最优加括号位置信息,递归地打印出最优的加括号位置。


main 方法:

public static void main(String[] args) {int[] m = { 3, 2, 5, 10, 2, 3 };matrix1(m);
}

这是程序的入口,在这里创建了一个整型数组 m,表示矩阵的维度。然后调用 matrix1 方法来解决矩阵连乘问题。

🎃总代码:

package test20210110;public class Test01 {public static void matrix1(int[] p) {int n = p.length - 1;int[][] x = new int[n][n];int[][] y = new int[n][n];for (int l = 2; l <= n; l++) {for (int i = 0; i < n - l + 1; i++) {int j = i + l - 1;x[i][j] = Integer.MAX_VALUE;for (int k = i; k < j; k++) {int q = x[i][k] + x[k + 1][j] + p[i] * p[k + 1] * p[j + 1];if (q < x[i][j]) {x[i][j] = q;y[i][j] = k;}}}}System.out.println("相乘次数最少的加括号的位置为:");print(y, 0, n - 1);System.out.println();System.out.println("最少相乘次数:" + x[0][n - 1]);}public static void print(int[][] s, int i, int j) {if (i == j) {System.out.print("A" +(i+1));} else {System.out.print("(");print(s, i, s[i][j]);print(s, s[i][j] + 1, j);System.out.print(")");}}public static void main(String[] args) {int[] m = { 3, 2, 5, 10, 2, 3 };matrix1(m);}
}

🎃 运行截图:


 💻two:

🎃问题:

2)0-1背包问题:有5个物品,其重量分别为{2,2,6,5,4},价值分别为{6,3,5,4,6}。背包容量为10,物品不可分割,求装入背包的物品和获得的最大价值。

🎃解题思路:

首先,定义一个二维数组 dp,其中 dp[i][j] 表示在前 i 个物品中,背包容量为 j 时能够获得的最大价值。

然后,初始化边界条件。当没有物品可选或者背包容量为0时,最大价值都为0。因此,可以将 dp[0][j]dp[i][0](其中0 ≤ i ≤ 5,0 ≤ j ≤ 10)都设置为0。

接下来,通过两层循环遍历物品和背包容量。外层循环表示当前所选物品的数量,从1到5;内层循环表示背包容量,从1到10。

在每次迭代中,分为两种情况进行考虑:

  1. 若当前物品重量大于当前背包容量,则无法选择该物品,因此 dp[i][j] 的值与 dp[i-1][j] 相等。
  2. 若当前物品重量小于等于当前背包容量,则需要进行选择。可以比较将该物品放入背包后的总价值与不放入该物品的总价值,选择其中较大的一个。即 dp[i][j] 的值为 max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]),其中 w[i] 表示第 i 个物品的重量,v[i] 表示第 i 个物品的价值。

完成所有的循环后,dp[5][10] 中存储的即为装入背包的物品能够获得的最大价值。

🎃代码分析:

首先,定义了一个 Value 类,并在 main 方法中编写了解决0-1背包问题的代码。

int[] weight = { 2, 2, 6, 5, 4 };
int[] value = { 6, 3, 5, 4, 6 };
int a = 10;int[][] dp = new int[weight.length + 1][a + 1];

以上代码定义了物品的重量数组 weight、价值数组 value 和背包容量 a。同时,创建了一个二维数组 dp,大小为 (weight.length + 1) × (a + 1),用于存储状态转移的结果。 


for (int i = 1; i <= weight.length; i++) {for (int j = 1; j <= a; j++) {if (j >= weight[i - 1]) {dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1]);} else {dp[i][j] = dp[i - 1][j];}}
}

以上代码通过两层循环遍历物品和背包容量,实现了动态规划的过程。在每次迭代中,根据当前物品重量和背包容量的大小关系,选择将该物品放入背包还是不放入背包,并更新 dp 数组中相应位置的值。

具体而言,如果当前物品的重量小于等于背包容量,则需要考虑将该物品放入背包后是否能够获得更大的总价值。通过比较不放入该物品和放入该物品两种情况下的总价值,选择其中较大的一个,并更新 dp[i][j] 的值。

如果当前物品的重量大于背包容量,则无法放入该物品,直接将 dp[i][j] 的值设为上一个状态 dp[i-1][j] 的值。


System.out.print("装入的物品是第");
int i = weight.length;
int j = a;
while (i > 0 && j > 0) {if (dp[i][j] != dp[i - 1][j]) {System.out.print(i + "个,");j -= weight[i - 1];}i--;
}System.out.println("\n最大价值为:" + dp[weight.length][a]);

 以上代码用于输出装入背包的物品和获得的最大价值。通过回溯的方式,从 dp 数组中找到装入背包的物品。具体来说,从右下角开始遍历 dp 数组,如果当前位置的值不等于上一个状态的值,说明选择了第 i 个物品放入背包,输出 i 并更新背包容量 j。然后,向左上方移动,继续遍历。

最后,输出最大价值,即 dp[weight.length][a] 的值。

🎃总代码:

package one;public class Value {public static void main(String[] args) {int[] weight = { 2, 2, 6, 5, 4 };int[] value = { 6, 3, 5, 4, 6 };int a = 10;int[][] dp = new int[weight.length + 1][a + 1];for (int i = 1; i <= weight.length; i++) {for (int j = 1; j <=a; j++) {if (j >= weight[i - 1]) {dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1]);} else {dp[i][j] = dp[i - 1][j];}}}System.out.print("装入的物品是第");int i = weight.length;int j = a;while (i > 0 && j > 0) {if (dp[i][j] != dp[i - 1][j]) {System.out.print(i + "个,");j -= weight[i - 1];}i--;}System.out.println("\n最大价值为:" + dp[weight.length][a]);}
}

🎃运行截图:


 💻three:

🎃问题:

最长公共子序列问题:求X={A,B,C,B,D,A,B}和Y={B,D,C,A,B,A}的最长公共子序列。

🎃解题思路:

最长公共子序列(Longest Common Subsequence,LCS)问题是经典的动态规划问题之一。给定两个序列 X 和 Y,找出它们的最长公共子序列的长度。

对于序列 X={A,B,C,B,D,A,B} 和 Y={B,D,C,A,B,A},可以采用动态规划的方法来解决最长公共子序列问题。下面是解题的思路和步骤:

  1. 定义状态: 创建一个二维数组 dp,其中 dp[i][j] 表示序列 X 的前 i 个元素与序列 Y 的前 j 个元素的最长公共子序列的长度。

  2. 状态转移方程: 根据动态规划的性质,我们可以使用以下状态转移方程来计算 dp[i][j]

    • 如果 X[i-1] == Y[j-1],即序列 X 的第 i-1 个元素和序列 Y 的第 j-1 个元素相等,那么 dp[i][j] = dp[i-1][j-1] + 1,表示当前这对匹配的字符可以贡献到最长公共子序列的长度中。
    • 如果 X[i-1] != Y[j-1],即序列 X 的第 i-1 个元素和序列 Y 的第 j-1 个元素不相等,那么 dp[i][j] = max(dp[i-1][j], dp[i][j-1]),表示当前位置的最长公共子序列长度取决于去掉 X 的最后一个元素时和去掉 Y 的最后一个元素时哪个更长。
  3. 初始化边界条件: 对于 dp 数组的第一行和第一列,因为其中一个序列为空时,最长公共子序列的长度必定为 0,所以将其初始化为 0。

  4. 填充表格: 根据状态转移方程,从 dp[0][0] 开始,逐行或逐列填充 dp 数组,直到填满整个表格。

  5. 回溯求解: 最后根据填充好的 dp 数组,可以进行回溯来找到具体的最长公共子序列。

通过以上步骤,就可以求解出序列 X 和 Y 的最长公共子序列的长度。希望这个解题思路能够帮助你理解如何使用动态规划来解决最长公共子序列问题。

🎃代码分析:

main 方法:

	public static void main(String[] args) {// TODO Auto-generated method stubString X = "ABCBDAB";String Y = "BDCABA";int[][] C = LCSLength(X, Y);System.out.println("最长公共子序列长度为:" + C[X.length()][Y.length()]);System.out.print("最长公共子序列为:");printLCS(C, X, Y, X.length(), Y.length());}

  • 在主方法中定义了两个字符串 X 和 Y,分别为 "ABCBDAB" 和 "BDCABA"。
  • 创建一个二维数组 C,并调用 LCSLength 方法计算最长公共子序列的长度,并将结果存储在数组 C 中。
  • 打印最长公共子序列的长度。
  • 调用 printLCS 方法,传入数组 C、字符串 X、字符串 Y 以及字符串 X 和 Y 的长度,打印最长公共子序列。

LCSLength 方法:

	public static int[][] LCSLength(String X, String Y) {int m = X.length();int n = Y.length();int[][] C = new int[m + 1][n + 1];for (int i = 0; i <= m; i++) {C[i][0] = 0;}for (int j = 0; j <= n; j++) {C[0][j] = 0;}for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (X.charAt(i - 1) == Y.charAt(j - 1)) {C[i][j] = C[i - 1][j - 1] + 1;} else {C[i][j] = Math.max(C[i - 1][j], C[i][j - 1]);}}}return C;}
  • 此方法用于计算给定两个字符串 X 和 Y 的最长公共子序列的长度。
  • 首先获取字符串 X 和 Y 的长度并创建一个大小为 (m+1) x (n+1) 的二维数组 C,其中 m 和 n 分别是字符串 X 和 Y 的长度。
  • 初始化数组 C 的第一行和第一列为 0。
  • 使用两个嵌套的 for 循环遍历字符串 X 和 Y 的所有组合。
  • 如果 X.charAt(i-1) 等于 Y.charAt(j-1),则说明当前字符属于最长公共子序列,此时将 C[i][j] 设置为 C[i-1][j-1] + 1。
  • 否则,根据动态规划的规则选择 C[i-1][j] 和 C[i][j-1] 中的较大值赋给 C[i][j]。
  • 最后返回填充好的数组 C。

printLCS 方法:

	public static void printLCS(int[][] C, String X, String Y, int i, int j) {if (i == 0 || j == 0) {return;}if (X.charAt(i - 1) == Y.charAt(j - 1)) {printLCS(C, X, Y, i - 1, j - 1);System.out.print(X.charAt(i - 1));} else if (C[i - 1][j] >= C[i][j - 1]) {printLCS(C, X, Y, i - 1, j);} else {printLCS(C, X, Y, i, j - 1);}}
  • 此方法用于回溯求解最长公共子序列,并将其打印出来。
  • 如果 i 或 j 为 0,则表示已经回溯到了边界,直接返回。
  • 如果 X.charAt(i-1) 等于 Y.charAt(j-1),则说明当前字符属于最长公共子序列,递归调用 printLCS 方法继续向前找,并打印当前字符。
  • 否则,根据动态规划的规则,如果 C[i-1][j] 大于等于 C[i][j-1],则递归调用 printLCS 方法向上找;否则,递归调用 printLCS 方法向左找。

 🎃总代码:

package one;public class Sameple {public static void main(String[] args) {// TODO Auto-generated method stubString X = "ABCBDAB";String Y = "BDCABA";int[][] C = LCSLength(X, Y);System.out.println("最长公共子序列长度为:" + C[X.length()][Y.length()]);System.out.print("最长公共子序列为:");printLCS(C, X, Y, X.length(), Y.length());}public static int[][] LCSLength(String X, String Y) {int m = X.length();int n = Y.length();int[][] C = new int[m + 1][n + 1];for (int i = 0; i <= m; i++) {C[i][0] = 0;}for (int j = 0; j <= n; j++) {C[0][j] = 0;}for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (X.charAt(i - 1) == Y.charAt(j - 1)) {C[i][j] = C[i - 1][j - 1] + 1;} else {C[i][j] = Math.max(C[i - 1][j], C[i][j - 1]);}}}return C;}public static void printLCS(int[][] C, String X, String Y, int i, int j) {if (i == 0 || j == 0) {return;}if (X.charAt(i - 1) == Y.charAt(j - 1)) {printLCS(C, X, Y, i - 1, j - 1);System.out.print(X.charAt(i - 1));} else if (C[i - 1][j] >= C[i][j - 1]) {printLCS(C, X, Y, i - 1, j);} else {printLCS(C, X, Y, i, j - 1);}}
}

🎃运行截图:

🎯 做题方法总结:

动态规划(Dynamic Programming)是一种通过将问题划分为子问题并为子问题找到最优解来解决复杂问题的算法思想。它通常用于解决具有重叠子问题和最优子结构性质的问题。

以下是使用动态规划解决问题的一般步骤:

  1. 定义子问题: 确定问题可以被划分为若干个子问题。这些子问题通常与原问题相似,但规模较小。

  2. 建立状态转移方程: 定义问题的状态以及状态之间的关系。通过求解子问题,可以推导出原问题的解。

  3. 确定初始条件: 确定最小子问题的解,作为递归或迭代的起点。

  4. 填充表格或数组: 使用循环结构计算并填充数组或表格,以解决子问题。通常从最小子问题开始,逐步计算到原问题。

  5. 返回结果: 根据问题的要求,从填充的表格或数组中得出最终的结果。

下面是一个更具体的动态规划法解题的示例:

  1. 问题定义: 定义问题的具体要求。例如,求解最长公共子序列、最优路径、最大值等。

  2. 状态定义: 定义问题的状态。确定需要记录的信息,以及如何表示状态。

  3. 状态转移方程: 建立状态之间的关系。根据问题的性质和要求,确定状态之间的转移方式。

  4. 初始条件: 确定最小子问题的解,作为递归或迭代的起点。

  5. 计算顺序: 根据状态转移方程,确定计算子问题的顺序。通常从最小子问题开始,逐步计算到原问题。

  6. 填充表格或数组: 使用循环结构计算并填充数组或表格,以解决子问题。根据计算顺序,依次填充表格中的每个元素。

  7. 返回结果: 根据问题的要求,从填充的表格或数组中得出最终的结果。

需要注意的是,动态规划法适用于具有重叠子问题和最优子结构性质的问题。在实际应用中,可以根据具体问题的特点灵活运用动态规划思想,设计合适的状态和状态转移方程,以提高问题的求解效率。

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

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

相关文章

YB75XXH系列是采用CMOS工艺制造,低功耗的高压稳压器

YB75xxH 高耐压线性稳压器 ■产品简介&#xff1a; YB75XXH系列是采用CMOS工艺制造&#xff0c;低功耗的高压稳压器&#xff0c;最高输入电压可达25V,输出电压范围为1.5V一12.0V。它具有高精度的输出电压、极低的供电电流、极低的跌落电压等特点。 ■产品特点&#xff1a; …

TCP_滑动窗口介绍

简介 TCP协议中有两个窗口&#xff0c;滑动窗口和拥塞窗口&#xff0c;两者均是一种流控机制&#xff1b;滑动窗口是接收方的流控机制&#xff0c;拥塞窗口是发送方的流控机制。 本文介绍滑动窗口&#xff0c;接收方为TCP连接设置了接收缓存。当TCP连接接收到正确、按序的字节…

[SWPUCTF 2021 新生赛]Do_you_know_http已

打开环境 它说用WLLM浏览器打开&#xff0c;使用BP抓包&#xff0c;发送到重发器 修改User-Agent 下一步&#xff0c;访问a.php 这儿他说添加一个本地地址&#xff0c;它给了一个183.224.40.160&#xff0c;我用了发现没用&#xff0c;然后重新添加一个地址&#xff1a;X-Forwa…

网络爬虫之多任务数据采集(多线程、多进程、携程)

进程&#xff1a;操作系统中资源分配的基本单位 线程&#xff1a;使用进程资源处理具体任务 一个进程中可以有多个线程&#xff1a;进程相当于一个公司&#xff0c;线程是公司里面的员工。 一 多线程 多线程都是关于功能的并发执行。而异步编程是关于函数之间的非阻塞执行&…

linux 中 C++的环境搭建以及测试工具的简单介绍

文章目录 makefleCMakegdb调试 与 coredumpValgrind 内存检测gtest 单元测试 makefile 介绍 安装 : sudo apt install make makefile 的规则: 举例说明 包括&#xff1a;目标文件 、 依赖文件 、 生成规则 使用 &#xff1a; make make clean CMake : CMake是一个…

【基于激光雷达的路沿检测用于自动驾驶的真值标注】

文章目录 概要主要贡献内容概述实验小结 概要 论文地址&#xff1a;https://arxiv.org/pdf/2312.00534.pdf 路沿检测在自动驾驶中扮演着重要的角色&#xff0c;因为它能够帮助车辆感知道可行驶区域和不可行驶区域。为了开发和验证自动驾驶功能&#xff0c;标注的数据是必不可…

【SpringBoot篇】基于Redis实现生成全局唯一ID的方法

文章目录 &#x1f354;生成全局唯一ID&#x1f339;为什么要生成全局唯一id&#x1f33a;生成全局id的方法✨代码实现 &#x1f354;生成全局唯一ID 是一种在分布式系统下用来生成全局唯一id的工具 在项目中生成全局唯一ID有很多好处&#xff0c;其中包括&#xff1a; 数据…

革命性突破:Great River推出XL高速ARINC 818传感器测试卡

Great River Technology荣幸地宣布&#xff0c;与RVS&#xff08;远程视觉系统&#xff09;2.0平台合作推出的XL高速ARINC 818传感器测试卡正式亮相。这款开创性的测试卡在柯林斯航空电子公司&#xff08;RTX业务部&#xff09;和波音公司开发和测试RVS 2.0系统中发挥了重要作用…

Python办公自动化Day1

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;xlwt创建Excelxlrd读取Excelxlutils修改Excelxlwt设置样式常见的字体样式单元格宽高内容对齐方式设置单元格边框设置背景颜色样式整合起来的写法 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编…

引领汽车营销新趋势,3DCAT实时云渲染助力汽车三维可视化

当前&#xff0c;汽车产业发展正从电动化的上半场&#xff0c;向智能化的下半场迈进。除了车机技术体验的智能化之外&#xff0c;观车体验的智能化也不容忽视。 这是因为&#xff0c;随着数字化、智能化、个性化的趋势&#xff0c;消费者对汽车的需求和期待也越来越高&#xf…

听GPT 讲Rust源代码--src/tools(23)

File: rust/src/tools/clippy/rustc_tools_util/src/lib.rs 在Rust源代码中&#xff0c;rust/src/tools/clippy/rustc_tools_util/src/lib.rs文件的作用是为Clippy提供了一些实用工具和辅助函数。 该文件中定义了VersionInfo结构体&#xff0c;它有三个字段&#xff0c;分别为m…

web架构师编辑器内容-创建业务组件和编辑器基本行为

编辑器主要分为三部分&#xff0c;左侧是组件模板库&#xff0c;中间是画布区域&#xff0c;右侧是面板设置区域。 左侧是预设各种组件模板进行添加 中间是使用交互手段来更新元素的值 右侧是使用表单的方式来更新元素的值。 大致效果&#xff1a; 左侧组件模板库 最初的模板…

微前端样式隔离、sessionStorage、localStorage隔离

1、样式隔离 前端样式不隔离&#xff0c;会产生样式冲突的问题&#xff0c;这个点在qiankun也存在 子应用1修改一个样式 button {background: red&#xff01;important&#xff1b; }其它应用也会受到影响 qiankun的css隔离方案&#xff08;shadow dom&#xff09; shadow …

FCIS 2023网络安全创新大会-核心PPT资料下载

一、峰会简介 本次会议的主题是“AI大模型、人工智能与智能制造安全、攻击面管理与供应链安全”。 1、AI大模型 会议首先探讨了AI大模型在网络安全领域的应用。AI大模型是一种基于深度学习的模型&#xff0c;具有强大的特征提取和分类能力&#xff0c;可以用于检测和防御各种…

MFC 自定义压缩,解压缩工具

界面效果如下&#xff1a; 对外提供的接口如下&#xff1a; public: void setCallback(zp::Callback callback, void* param); bool open(const zp::String& path, bool readonly false); bool create(const zp::String& path, const zp::String& inputPath)…

代码图形注释自动生成(通过文字图像)

0. 简介 大家在学&#xff08;CTRL&#xff09;习&#xff08;C&#xff09;别人代码的时候&#xff0c;看到别人的代码程序&#xff0c;在日志中有很多很酷的代码注释&#xff0c;或者是有一些图形化注释方便理解。之前本人以为都是一个个手敲出来的。然后在网上一番搜索&…

STM32G4x FLASH 读写配置结构体(LL库下使用)

主要工作就是把HAL的超时用LL库延时替代&#xff0c;保留了中断擦写模式、轮询等待擦写&#xff0c;我已经验证了部分。 笔者用的芯片为STM32G473CBT6 128KB Flash&#xff0c;开环环境为CUBEMXMDK5.32&#xff0c;因为G4已经没有标准库了&#xff0c;笔者还是习惯使用标准库的…

Ubuntu 常用命令之 fdisk 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 fdisk 是一个用于处理磁盘分区的命令行工具&#xff0c;它在 Linux 系统中广泛使用。fdisk 命令可以创建、删除、更改、复制和显示硬盘分区&#xff0c;以及更改硬盘的分区 ID。 fdisk 命令的常用参数如下 -l&#xff1a;列出所…

threejs中修改鼠标cursor不生效的问题修复

需求&#xff1a; 当鼠标hover一个元素时&#xff0c;cursor为自定义的图标 问题描述&#xff1a; threejs中修改canvas的鼠标cursor为自定义的图标不生效。 问题原因&#xff1a; 引入了dragcontrols&#xff0c;查看dragControls的代码&#xff0c;可以看到代码中有对cur…

鸿蒙ArkTS语言介绍与TS基础语法

1、ArkTS介绍 ArkTS是HarmonyOS主力应用开发语言&#xff0c;它在TS基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等响应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 JS 是一种属于网络的高级脚本语言&#xff0c;已经被广泛用…