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

🎃个人专栏:

🐬 算法设计与分析:算法设计与分析_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 stub
		String 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 stub
		String 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. 返回结果: 根据问题的要求,从填充的表格或数组中得出最终的结果。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于“Python”的核心知识点整理大全36

目录 13.4.4 向下移动外星人群并改变移动方向 game_functions.py alien_invasion.py 13.5 射杀外星人 13.5.1 检测子弹与外星人的碰撞 game_functions.py alien_invasion.py 13.5.2 为测试创建大子弹 13.5.3 生成新的外星人群 game_functions.py alien_invasion.py …

【github】github设置项目为私有

点击setting change to private 无脑下一步

为什么c++的开源库那么少?

为什么c的开源库那么少&#xff1f; 在开始前我有一些资料&#xff0c;是我根据自己从业十年经验&#xff0c;熬夜搞了几个通宵&#xff0c;精心整理了一份「c的资料从专业入门到高级教程工具包」&#xff0c;点个关注&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&…

热部署 和 热加载

本文主要讲热部署和热加载的区别、原理&#xff0c;以及常用的热部署的方式实践心得&#xff0c;其中包括HotSwap、Spring-loaded、Spring-boot-devtools、HotCode2和JRebel&#xff0c;诸多方式任你选择&#xff0c;希望能为你的开发进一步提效 1 热部署和热加载 开篇先说下热…

在Linux系统中安装MySQL数据库

目录 一、MySQL简介 二、MySQL安装步骤 1、下载MySQL的YUM仓库文件 2、安装MySQL源 3、解决密钥异常问题 4、安装MySQL服务器 5、开启MySQL服务 6、查看MySQL服务器中root用户的初始密码 7、使用初始密码登录MySQL服务器 8、修改root用户登录MySQL服务器的密码 三、…

使用Java语言判断一个年度是不是闰年

一、 代码说明 引入Scanner函数&#xff0c;将类命名为Judge类&#xff0c;使用try语句和catch语句将整体代码包围起来&#xff0c;使用if语句来判断是否为闰年&#xff0c;输入年份&#xff0c;然后得到相应的结论。 二、代码 import java.util.Scanner; public class Judg…

ElementUI中修改el-table的滚动条样式

注意&#xff1a;本文仅基于webkit引擎浏览器&#xff1b; 如果是火狐浏览器&#xff0c;则是-moz-&#xff1b; 部分webkit引擎浏览器&#xff1a;Google Chrome谷歌浏览器、Safari浏览器、搜狗高速浏览器、QQ浏览器、360极速浏览器等… 当内容超出容器时会出现滚动条&#…

HarmonyOS4.0系统性深入开发01应用模型的构成要素

应用模型的构成要素 应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。有了应用模型&#xff0c;开发者可以基于一套统一的模型进行应用开发&#xff0c;使应用开发更简单、高效。 HarmonyOS应用模型的构成要…

Spring基础-IOC-DI-AOP

第一部分:Spring基础 文章目录 第一部分:Spring基础一、核心概念1.什么是Spring?2.Spring架构3.Spring优势 二、控制反转1.为什么要控制反转?2.组件化方式编程案例(Test01_di)3.采用组件化思维,装配打印机(Test01_di) 三、面向切面编程(AOP)方面编程1.什么是AOP?2.如何实现A…

AI时代Python量化交易实战:ChatGPT引领新时代

文章目录 《AI时代Python量化交易实战&#xff1a;ChatGPT让量化交易插上翅膀》关键点内容简介作者简介购买链接 《AI时代架构师修炼之道&#xff1a;ChatGPT让架构师插上翅膀》关键点内容简介作者简介 赠书活动 《AI时代Python量化交易实战&#xff1a;ChatGPT让量化交易插上翅…

MATLAB - 读取双摆杆上的 IMU 数据

系列文章目录 前言 本示例展示了如何从安装在双摆杆上的两个 IMU 传感器生成惯性测量单元 (IMU) 读数。双摆使用 Simscape Multibody™ 进行建模。有关使用 Simscape Multibody™ 构建简易摆的分步示例&#xff0c;请参阅简易摆建模&#xff08;Simscape Multibody&#xff09…

设计模式(4)--对象行为(2)--命令

1. 意图 将一个请求封装为一个对象&#xff0c;从而使你可用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请 求日志&#xff0c;以及支持可撤销的操作。 2. 四种角色 接收者(Receiver)、抽象命令(Command)、具体命令(Concrete Command)、请求者(Invoker) 3. 优点…

【NI-RIO入门】使用其他文本语言开发CompactRIO

1.FPGA 接口Python API Getting Started — FPGA Interface Python API 19.0.0 documentation 2.FPGA接口C API FPGA 接口 C API 是用于 NI 可重配置 I/O (RIO) 硬件&#xff08;例如 NI CompactRIO、NI Single-Board RIO、NI 以太网 RIO、NI FlexRIO、NI R 系列多功能 RIO 和…

Python生成圣诞节贺卡-代码案例剖析【第18篇—python圣诞节系列】

文章目录 ❄️Python制作圣诞节贺卡&#x1f42c;展示效果&#x1f338;代码&#x1f334;代码剖析 ❄️Python制作圣诞树贺卡&#x1f42c;展示效果&#x1f338;代码&#x1f334;代码剖析&#x1f338;总结 &#x1f385;圣诞节快乐&#xff01; ❄️Python制作圣诞节贺卡 …

【数字通信原理】复习笔记

哈喽&#xff89;hi~ 小伙伴们许久没有更新啦~ 花花经历了漫长的考试周~ 要被累成花干啦。今天来更新《数字通信原理》手写笔记给需要的小伙伴~ &#xff08;注:这是两套笔记&#xff0c;是需要结合来看的哦~&#xff09; 第一套的笔记请结合bilibili:张锦皓的复习课程来哦。 第…

sql_lab之sqli中的报错注入,less13

报错注入&#xff08;less-13&#xff09; 正常报错注入&#xff1a; 1.输入用户名和密码123 123显示登录错误 2.输入用户名和密码123’ 123显示登录错误 123后面有’)说明是’)注入 3.查询数据库名 1) and updatexml(<a><b></b></a>,concat(1111…

二维码智慧门牌管理系统升级:强化用户管理合规性

文章目录 前言一、功能优化和多层级管理二、强大的合规性与权限配置三、提升管理效率与系统安全性 前言 随着科技迅速发展&#xff0c;二维码智慧门牌管理系统已经成为各组织机构首选的入口&#xff0c;提高了信息管理效率并确保了数据安全。然而&#xff0c;用户需求变化和法…

<HarmonyOS第一课>运行Hello World

下载与安装DevEco Studio 在HarmonyOS应用开发学习之前&#xff0c;需要进行一些准备工作&#xff0c;首先需要完成开发工具DevEco Studio的下载与安装以及环境配置。 进入DevEco Studio下载官网&#xff0c;单击“立即下载”进入下载页面。 DevEco Studio提供了Windows版本和…

OC学习笔记--基础篇

本文简要介绍了一些oc的基础类型&#xff0c;包括数组、字典、字符串、消息传递、类、对象、方法、属性、协议和转发&#xff0c;希望对你有帮助。 OC数据类型 打印—类似print NSlog("hello word");数组 NSMutableArray &#xff08;可变数组&#xff09;和 NSAr…

音画欣赏|《同杯万古尘》

《同杯万古尘》 尺寸&#xff1a;69x35cm 陈可之2023年绘 《拟古十二首-其九》 李白 生者为过客&#xff0c;死者为归人。 天地一逆旅&#xff0c;同悲万古尘。 月兔空捣药&#xff0c;扶桑已成薪。 白骨寂无言&#xff0c;青松岂知春。 前后更叹息&#xff0c;浮荣安足珍&am…