代码随想录-Day41

46. 携带研究材料(第六期模拟笔试)在这里插入图片描述

题目描述
小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的空间,并且具有不同的价值。

小明的行李空间为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料只能选择一次,并且只有选与不选两种选择,不能进行切割。

输入描述
第一行包含两个正整数,第一个整数 M 代表研究材料的种类,第二个正整数 N,代表小明的行李空间。

第二行包含 M 个正整数,代表每种研究材料的所占空间。

第三行包含 M 个正整数,代表每种研究材料的价值。

输出描述
输出一个整数,代表小明能够携带的研究材料的最大价值。
输入示例
6 1
2 2 3 1 5 2
2 3 1 5 4 3
输出示例
5
提示信息
小明能够携带 6 种研究材料,但是行李空间只有 1,而占用空间为 1 的研究材料价值为 5,所以最终答案输出 5。

数据范围:
1 <= N <= 5000
1 <= M <= 5000
研究材料占用空间和价值都小于等于 1000

方法一:

public class BagProblem {public static void main(String[] args) {int[] weight = {1,3,4};int[] value = {15,20,30};int bagSize = 4;testWeightBagProblem(weight,value,bagSize);}/*** 动态规划获得结果* @param weight  物品的重量* @param value   物品的价值* @param bagSize 背包的容量*/public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){// 创建dp数组int goods = weight.length;  // 获取物品的数量int[][] dp = new int[goods][bagSize + 1];// 初始化dp数组// 创建数组后,其中默认的值就是0for (int j = weight[0]; j <= bagSize; j++) {dp[0][j] = value[0];}// 填充dp数组for (int i = 1; i < weight.length; i++) {for (int j = 1; j <= bagSize; j++) {if (j < weight[i]) {/*** 当前背包的容量都没有当前物品i大的时候,是不放物品i的* 那么前i-1个物品能放下的最大价值就是当前情况的最大价值*/dp[i][j] = dp[i-1][j];} else {/*** 当前背包的容量可以放下物品i* 那么此时分两种情况:*    1、不放物品i*    2、放物品i* 比较这两种情况下,哪种背包中物品的最大价值最大*/dp[i][j] = Math.max(dp[i-1][j] , dp[i-1][j-weight[i]] + value[i]);}}}// 打印dp数组for (int i = 0; i < goods; i++) {for (int j = 0; j <= bagSize; j++) {System.out.print(dp[i][j] + "\t");}System.out.println("\n");}}
}

这段Java代码实现了一个基于动态规划(Dynamic Programming, DP)的方法来解决经典的“0-1背包问题”。0-1背包问题是指有一个背包,最大承重为bagSize,同时有goods件物品,每件物品都有自己的重量weight[i]和价值value[i]。目标是确定每件物品放或不放的选择方案,使得放入背包的物品总价值最大,同时不超过背包的承重限制。

解析

  1. 初始化DP数组:

    • dp[i][j]表示在只考虑前i件物品的情况下,当背包容量为j时能装入物品的最大总价值。
    • 初始化第一行时,考虑的是只有第一件物品时的情况,因此当背包容量大于等于第一件物品的重量时,可以选择放入该物品,dp[0][j] = value[0]
  2. 填充DP数组:

    • 外层循环遍历所有物品。
    • 内层循环遍历从0到背包最大容量bagSize的所有可能容量。
    • 对于每个dp[i][j],有两种选择:
      • 不放入第i件物品,此时的最大价值等于前i-1件物品在容量为j时的最大价值,即dp[i-1][j]
      • 如果放入第i件物品(前提是当前背包容量j大于等于第i件物品的重量weight[i]),则需要从背包剩余容量中减去当前物品的重量,查看剩余容量下的最大价值,即dp[i-1][j-weight[i]] + value[i],然后与不放该物品的情况比较取最大值。
  3. 打印DP数组:

    • 最后,通过双层循环遍历并打印出整个dp数组,帮助我们直观地理解每一步决策过程及最终结果。

结果

虽然代码中包含了打印dp数组的过程以供观察,但实际应用中,我们通常只关心最终结果,即dp[goods-1][bagSize],它表示在考虑所有物品和背包容量限制下能够获取的最大价值。不过,这段代码未直接输出这个结果,如果你需要看到具体的最优解,可以在打印数组之后添加一行代码输出dp[goods-1][bagSize]

方法二:

import java.util.Arrays;public class BagProblem {public static void main(String[] args) {int[] weight = {1,3,4};int[] value = {15,20,30};int bagSize = 4;testWeightBagProblem(weight,value,bagSize);}/*** 初始化 dp 数组做了简化(给物品增加冗余维)。这样初始化dp数组,默认全为0即可。* dp[i][j] 表示从下标为[0 - i-1]的物品里任意取,放进容量为j的背包,价值总和最大是多少。* 其实是模仿背包重量从 0 开始,背包容量 j 为 0 的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为 0。* 可选物品也可以从无开始,也就是没有物品可选,即dp[0][j],这样无论背包容量为多少,背包价值总和一定为 0。* @param weight  物品的重量* @param value   物品的价值* @param bagSize 背包的容量*/public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){// 创建dp数组int goods = weight.length;  // 获取物品的数量int[][] dp = new int[goods + 1][bagSize + 1];  // 给物品增加冗余维,i = 0 表示没有物品可选// 初始化dp数组,默认全为0即可// 填充dp数组for (int i = 1; i <= goods; i++) {for (int j = 1; j <= bagSize; j++) {if (j < weight[i - 1]) {  // i - 1 对应物品 i/*** 当前背包的容量都没有当前物品i大的时候,是不放物品i的* 那么前i-1个物品能放下的最大价值就是当前情况的最大价值*/dp[i][j] = dp[i - 1][j];} else {/*** 当前背包的容量可以放下物品i* 那么此时分两种情况:*    1、不放物品i*    2、放物品i* 比较这两种情况下,哪种背包中物品的最大价值最大*/dp[i][j] = Math.max(dp[i - 1][j] , dp[i - 1][j - weight[i - 1]] + value[i - 1]);  // i - 1 对应物品 i}}}// 打印dp数组for(int[] arr : dp){System.out.println(Arrays.toString(arr));}}
}

这段代码是使用Java实现的解决0-1背包问题的改进版本,通过动态规划(Dynamic Programming, DP)方法计算在给定背包容量和每件物品的重量、价值的情况下,能够获取的最大价值。相比之前的版本,这里的实现做了些微调和优化,特别是对动态规划数组的初始化进行了简化,并在代码中增加了详细的注释来解释每一步的操作。下面是代码的详细解析:

代码解析

  1. 初始化改进:在定义dp数组时,增加了一个冗余维度,使得物品编号从1到goods对应于数组下标0到goods-1,这样的好处是在计算时不需要特别处理边界情况,直接遍历即可,简化了逻辑。dp[i][j]的含义是考虑前i件物品,背包容量为j时的最大价值。

  2. 简化初始化:由于dp数组被初始化为全0,这已经符合了动态规划的初始条件——即没有物品可选或背包容量为0时,价值总和为0。因此,去除了显式的初始化步骤,直接进入填充阶段。

  3. 填充DP数组

    • 双重循环遍历每一件物品和每一个可能的背包容量。对于每个状态dp[i][j]
      • 若当前背包容量j不足以容纳第i件物品(即j < weight[i-1]),则不选第i件物品,价值继承自不选此物品的最大价值,即dp[i][j] = dp[i-1][j]
      • 若背包容量足够,需要在不选第i件物品(价值dp[i-1][j])和选择第i件物品(价值dp[i-1][j-weight[i-1]] + value[i-1])中取最大值,以最大化背包总价值。
  4. 打印结果:最后,通过遍历并打印dp数组,可以直观地查看每一步动态规划的决策过程,虽然在实际应用中可能并不需要打印,但有助于理解和调试。

结果分析

代码执行后,dp[goods][bagSize]即为所能获取的最大价值。不过,需要注意的是,代码最后打印的是整个dp数组的状态,而不是直接输出最大价值。如果需要直接获取并打印最大价值,可以在循环结束后添加一行代码,如System.out.println(dp[goods][bagSize]);

方法三:

在这里插入图片描述

    public static void main(String[] args) {int[] weight = {1, 3, 4};int[] value = {15, 20, 30};int bagWight = 4;testWeightBagProblem(weight, value, bagWight);}public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){int wLen = weight.length;//定义dp数组:dp[j]表示背包容量为j时,能获得的最大价值int[] dp = new int[bagWeight + 1];//遍历顺序:先遍历物品,再遍历背包容量for (int i = 0; i < wLen; i++){for (int j = bagWeight; j >= weight[i]; j--){dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);}}//打印dp数组for (int j = 0; j <= bagWeight; j++){System.out.print(dp[j] + " ");}}

这段Java代码实现了一个简化版的0-1背包问题的动态规划解法。0-1背包问题的目标是:给定一组物品,每种物品都有自己的重量和价值,在限定的总重量内,选取哪些物品可以使得总价值最大。下面是对这段代码的详细解析:

主函数

  • 定义了物品的重量数组weight、价值数组value以及背包的最大承重bagWeight
  • 调用testWeightBagProblem方法求解最大价值。

testWeightBagProblem 方法

  1. 初始化:首先获取物品的数量wLen,并定义一个长度为bagWeight + 1的数组dpdp[j]表示当背包容量为j时,能够装入物品的最大总价值。

  2. 双重循环

    • 外层循环遍历每个物品(从0到wLen-1)。
    • 内层循环从背包的最大容量bagWeight反向遍历到当前物品的重量。这样的遍历顺序保证了在计算dp[j]时,已经处理了所有比当前物品轻的物品,利用了之前计算的结果,体现了动态规划的“状态转移”。
  3. 状态转移方程:在内层循环中,对于每个背包容量j,有两种选择:

    • 不放入第i件物品,此时背包的最大价值保持不变,即dp[j] = dp[j]
    • 放入第i件物品,背包的当前容量减去该物品的重量j - weight[i],背包的最大价值变为之前的最大价值加上当前物品的价值,即dp[j - weight[i]] + value[i]
    • 使用Math.max()函数选择这两种情况中的较大值作为新的dp[j],表示在考虑放入第i个物品后,容量为j的背包能够达到的最大价值。
  4. 打印结果:最后,代码遍历并打印dp数组,展示在不同背包容量下能够达到的最大价值。

注意点

  • 这个版本的代码通过逆序遍历背包容量,避免了需要初始化第一排和第一列的麻烦,直接从空背包(容量为0)开始计算,逐渐增加背包容量。
  • 由于是从大到小遍历背包容量,所以在考虑放入当前物品时,之前容量较小的情况已经计算完成,可以直接利用,保证了动态规划的“从已知求未知”的原则。

416. 分割等和子集

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2:

输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。

提示:

1 <= nums.length <= 200
1 <= nums[i] <= 100

方法一:

class Solution {public boolean canPartition(int[] nums) {if(nums == null || nums.length == 0) return false;int n = nums.length;int sum = 0;for(int num : nums) {sum += num;}//总和为奇数,不能平分if(sum % 2 != 0) return false;int target = sum / 2;int[] dp = new int[target + 1];for(int i = 0; i < n; i++) {for(int j = target; j >= nums[i]; j--) {//物品 i 的重量是 nums[i],其价值也是 nums[i]dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);}//剪枝一下,每一次完成內層的for-loop,立即檢查是否dp[target] == target,優化時間複雜度(26ms -> 20ms)if(dp[target] == target)return true;}return dp[target] == target;}
}

这段Java代码是用于解决“零钱兑换II”或类似问题的一个变种,准确地说,是判断一个整数数组nums中的元素是否可以分成两个子集,使得这两个子集的和相等。这是一种完全背包问题的变体,用于判断是否存在子集和为总和一半的情况。以下是代码的详细解析:

方法概览

  • 输入:一个整数数组nums
  • 输出:如果可以将数组分割成两个总和相等的子集,则返回true,否则返回false

核心逻辑

  1. 检查特殊情况:首先,检查数组是否为空或长度为0,若是,则直接返回false,因为不可能分割。
  2. 计算总和:计算数组元素的总和sum,如果sum是奇数,则直接返回false,因为不能平均分配。
  3. 目标值:设置目标值target为总和的一半。
  4. 初始化动态规划数组:创建一个长度为target + 1的数组dp,用于存储达到每个目标和的可能性。初始化所有值为0,因为一开始没有任何物品被选中。
  5. 填充动态规划数组:双层循环遍历每个物品和每个可能的目标和值。从数组中的每个元素开始,反向遍历到目标值,更新dp[j]max(dp[j], dp[j - nums[i]] + nums[i])。这一步是在考虑是否选择当前物品nums[i]以达到或更接近目标和j
  6. 剪枝优化:在内层循环结束后,检查是否已经找到了和为目标值的子集(dp[target] == target),如果是,则提前返回true,避免不必要的循环。
  7. 返回结果:最后,检查dp[target]是否等于target,如果等于则说明找到了满足条件的子集,返回true;否则返回false

性能优化

  • 剪枝:通过在内层循环结束后进行检查,一旦发现已达到目标和,就提前终止循环,这是一种有效的剪枝策略,可以减少不必要的计算,提高程序运行效率。

总的来说,这个方法通过动态规划有效地解决了能否将数组分割成两个和相等的子集的问题,同时通过剪枝策略进行了优化。

方法二 :二维数组版本(易于理解)

public class Solution {public static void main(String[] args) {int num[] = {1,5,11,5};canPartition(num);}public static boolean canPartition(int[] nums) {int len = nums.length;// 题目已经说非空数组,可以不做非空判断int sum = 0;for (int num : nums) {sum += num;}// 特判:如果是奇数,就不符合要求if ((sum %2 ) != 0) {return false;}int target = sum / 2; //目标背包容量// 创建二维状态数组,行:物品索引,列:容量(包括 0)/*dp[i][j]表示从数组的 [0, i] 这个子区间内挑选一些正整数每个数只能用一次,使得这些数的和恰好等于 j。*/boolean[][] dp = new boolean[len][target + 1];// 先填表格第 0 行,第 1 个数只能让容积为它自己的背包恰好装满  (这里的dp[][]数组的含义就是“恰好”,所以就算容积比它大的也不要)if (nums[0] <= target) {dp[0][nums[0]] = true;}// 再填表格后面几行//外层遍历物品for (int i = 1; i < len; i++) {//内层遍历背包for (int j = 0; j <= target; j++) {// 直接从上一行先把结果抄下来,然后再修正dp[i][j] = dp[i - 1][j];//如果某个物品单独的重量恰好就等于背包的重量,那么也是满足dp数组的定义的if (nums[i] == j) {dp[i][j] = true;continue;}//如果某个物品的重量小于j,那就可以看该物品是否放入背包//dp[i - 1][j]表示该物品不放入背包,如果在 [0, i - 1] 这个子区间内已经有一部分元素,使得它们的和为 j ,那么 dp[i][j] = true;//dp[i - 1][j - nums[i]]表示该物品放入背包。如果在 [0, i - 1] 这个子区间内就得找到一部分元素,使得它们的和为 j - nums[i]。if (nums[i] < j) {dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]];}}}for (int i = 0; i < len; i++) {for (int j = 0; j <= target; j++) {System.out.print(dp[i][j]+" ");}System.out.println();}return dp[len - 1][target];}
}
//dp数组的打印结果
false true false false false false false false false false false false 
false true false false false true true false false false false false 
false true false false false true true false false false false true 
false true false false false true true false false false true true 

这段Java代码实现了求解“分割等和子集”问题的动态规划算法。给定一个非空数组nums,判断是否可以将其分割成两个子集,使得两个子集的和相等。以下是代码的详细解析:

主要逻辑

  1. 初始化:首先,计算数组的总和sum,并检查总和是否为偶数。如果是奇数,则直接返回false,因为无法分割成两个和相等的子集。接着,设定目标和target为总和的一半。

  2. 创建DP数组:定义一个布尔类型的二维数组dp,其中dp[i][j]表示在前i个元素中是否存在一些元素的和等于j。数组的大小是len(数组长度)乘以target + 1,初始化为false

  3. 初始化DP数组的第一行:如果数组的第一个元素不大于目标和target,则dp[0][nums[0]]置为true,表示可以恰好装满容量为nums[0]的背包。

  4. 填充DP数组:通过两层循环遍历每个物品和每个可能的目标和。对于每个元素,有两种情况考虑:

    • 如果当前物品的值等于当前的容量j,那么可以单独装入背包,dp[i][j] = true
    • 如果当前物品的值小于当前的容量j,那么有两种选择:不选当前物品(继承上一行相同容量的状态dp[i-1][j])或者选当前物品(查看剩余容量j-nums[i]在上一行是否可以被满足,即dp[i-1][j-nums[i]])。如果这两种情况有任何一种为真,则dp[i][j] = true
  5. 输出和返回结果:最后,打印整个dp数组(用于调试查看状态转移过程),并返回dp[len - 1][target],即判断数组最后一个元素对应的背包容量target是否可以被满足。

输出解释

打印的dp数组展示了动态规划过程中每个状态的真假值,其中true表示存在一个子集的和等于当前列索引所表示的值。最后一行的最后一个元素(即dp[len - 1][target])为true,表明原数组可以分割成两个和为target的子集。

综上所述,这段代码有效地利用动态规划求解了“分割等和子集”问题。

方法三:二维数组整数版本

class Solution {public boolean canPartition(int[] nums) {//using 2-D DP array.int len = nums.length;//check edge cases;if(len == 0)return false;int sum = 0;for (int num : nums)sum += num;//we only deal with even numbers. If sum is odd, return false;if(sum % 2 == 1)return false;int target = sum / 2;int[][] dp = new int[nums.length][target + 1];// for(int j = 0; j <= target; j++){//     if(j < nums[0])//         dp[0][j] = 0;//     else//         dp[0][j] = nums[0];// }//initialize dp arrayfor(int j = nums[0]; j <= target; j++){dp[0][j] = nums[0];}for(int i = 1; i < len; i++){for(int j = 0; j <= target; j++){if (j < nums[i]) dp[i][j] = dp[i - 1][j];else dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);}}//print out DP array// for(int x : dp){//     System.out.print(x + ",");// }// System.out.print("    "+i+" row"+"\n");return dp[len - 1][target] == target;}
}
//dp数组的打印结果 for test case 1.
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
0, 1, 1, 1, 1, 5, 6, 6, 6, 6, 6, 6, 
0, 1, 1, 1, 1, 5, 6, 6, 6, 6, 6, 11, 
0, 1, 1, 1, 1, 5, 6, 6, 6, 6, 10, 11, 

这段Java代码实现了解决“分割等和子集”问题的动态规划算法。给定一个非空整数数组nums,判断是否可以将其分割成两个子集,使得两个子集的和相等。以下是代码的详细解释:

算法思路

  1. 预处理:首先计算数组nums的总和sum,并检查sum是否为偶数。如果是奇数,则直接返回false,因为无法均分为两个和相等的子集。如果为偶数,将目标和target设置为sum的一半。

  2. 初始化动态规划表:创建一个二维数组dp,其中dp[i][j]表示在前i个元素中是否存在子集的和等于j。数组的大小为nums.length乘以target + 1。注意,对于第一行的初始化有误,正确的初始化应该考虑nums[0]是否小于等于当前列索引j

  3. 填充动态规划表:遍历数组nums的每个元素,对于每个元素,从target开始反向遍历到nums[i](包括),更新dp[i][j]的值。有两种情况:

    • 如果当前背包容量j小于当前物品nums[i]的值,那么不选当前物品,状态继承自上一行,即dp[i][j] = dp[i - 1][j]
    • 否则,可以选择当前物品或者不选,取两者中能使得子集和等于j的最大可能性,即dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i])
  4. 返回结果:最后,检查dp[len - 1][target]是否等于target,如果等于则说明找到了一个子集和等于target,返回true;否则返回false

注意点

  • 代码中注释掉的部分是原始的错误初始化示例,正确的初始化逻辑已经在循环中通过条件判断实现了。
  • 另外,代码中还注释掉了打印dp数组的调试语句,这在开发过程中可用于观察动态规划表的构建过程,帮助理解算法的工作原理。

通过以上步骤,该算法有效地解决了给定数组是否可以分割成两个和相等的子集的问题。

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

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

相关文章

GroundingDINO1.5突破开放式物体检测界限:介绍与应用

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

小程序 UI 风格,引人入胜

小程序 UI 风格&#xff0c;引人入胜

如何基于项目人力和管线方案选择FGUI和UGUI

1&#xff09;如何基于项目人力和管线方案选择FGUI和UGUI 2&#xff09;TMP字体出包丢失字体描边 3&#xff09;如何将一张贴图经过Shader处理后的结果输出给另外一个Shader使用 4&#xff09;为什么我的水这么干净&#xff0c;和UE教程里的有差别 这是第390篇UWA技术知识分享的…

Handling `nil` Values in `NSDictionary` in Objective-C

Handling nil Values in NSDictionary in Objective-C When working with Objective-C, particularly when dealing with data returned from a server, it’s crucial (至关重要的) to handle nil values appropriately (适当地) to prevent unexpected crashes. Here, we ex…

2024年最新通信安全员考试题库

61.架设架空光缆&#xff0c;可使用吊板作业的情况是&#xff08;&#xff09;。 A.在2.2/7规格的电杆与墙壁之间的吊线上&#xff0c;吊线高度5m B.在2.2/7规格的墙壁与墙壁之间的吊线上&#xff0c;吊线高度6m C.在2.2/7规格的电杆与电杆之间的吊线上&#xff0c;吊线高度…

ChatGPT API技术教程OpenAI APIKey在线对接-Chat Completion对象

表示模型根据提供的输入返回的聊天完成响应。 {"id": "chatcmpl-123","object": "chat.completion","created": 1677652288,"model": "gpt-3.5-turbo-0125","system_fingerprint": "fp…

solidity智能合约如何实现跨合约调用函数

背景 比如现在有一个需求、我需要通过外部合约获取BRC20 token的总交易量。那么我需要在brc20的转账函数里面做一些调整&#xff0c;主要是两个函数内统计转移量。然后再提供外部获取函数。 /*** dev Sets amount as the allowance of spender over the callers tokens.** Ret…

【ai】tx2-nx:安装深度学习环境及4.6对应pytorch

参考:https://www.waveshare.net/wiki/Jetson_TX2_NX#AI.E5.85.A5.E9.97.A8 英伟达2021年发布的的tritionserver 2.17 版本中,backend 有tensorflow1 和 onnxruntime ,他们都是做什么用的,作为backend 对于 triton 推理server意义是什么,是否应该有pytorch? Triton Infer…

数据分析必备:一步步教你如何用matplotlib做数据可视化(13)

1、Matplotlib 文本 Matplotlib具有广泛的文本支持&#xff0c;包括对数学表达式的支持&#xff0c;对光栅和矢量输出的TrueType支持&#xff0c;具有任意旋转的换行符分隔文本以及unicode支持。Matplotlib包含自己的matplotlib.font_manager&#xff0c;它实现了一个跨平台&a…

modelsim做后仿真的一点思路

这是以TD_5.6.3_Release_88061生成的网表文件&#xff08;其他工具生成的网表文件类似&#xff09;&#xff0c;与modelsim联合进行门级仿真的样例&#xff0c;时序仿真与门级仿真的方法类似&#xff0c;只是增加了标准延时文件。 1、建立门级仿真工程 将门级网表和testbench添…

Redis-数据类型-Hash

文章目录 1、查看redis是否启动2、通过客户端连接redis3、切换到db3数据库4、插入新数据返回15、获取指定哈希&#xff08;hash&#xff09;对象的所有字段&#xff08;field&#xff09;名6、获取存储在指定哈希&#xff08;hash&#xff09;对象中的所有字段&#xff08;fiel…

OpenCV练习(2)图像校正

1、傅里叶变换 霍夫变换 直线 角度 旋转2、边缘检测 霍夫变换 直线角度 旋转3、四点透视 角度 旋转4、检测矩形轮廓 角度 旋转 1.目的 实现类似全能扫面王的图像校正功能 2. 基于轮廓提取和透射变换 基于轮廓提取和透射变换的矫正算法更适用于车牌、身份证、人民…

ue 材质贴图Tiling repeat

材质问题&#xff0c;如下 贴图显然不符合逻辑&#xff0c;太大&#xff0c;并且是一次性贴图 换一个红砖纹理&#xff0c;就看清了&#xff0c;砖太大了 修改&#xff1a; 拖出一个TexCoord&#xff0c;代表坐标&#xff0c;拖出一个参数&#xff0c;代表次数&#xff0c;如…

LDO芯片手册,实例应用分析

在进行电路设计时LDO是经常用到的&#xff0c;尤其在为芯片&#xff0c;晶振等敏感电路进行供电时应用更多&#xff0c;下面选取一款比较常用的LDO芯片&#xff0c;一起进行更深入的学习。 SGM2036特点简介 SGM2036&#xff0c;圣邦微一款比较常用的LDO芯片手册 可以先大致看…

用两个钟,我又在VMWARE上搞了一套内部网配置

最近要学es&#xff0c;所以打算自己用虚拟机搞个NAT&#xff0c;又搞了两个钟。为了不再费劲尝试&#xff0c;也为了造福大众&#xff0c;所以选择搞一份NAT笔记&#xff01;&#xff01;&#xff01;&#xff01; 1.初始化网关和DNS 我们给网关配置一个地址192.168.96.1&…

Vue41 ref属性

ref属性 ref是Vue提供的获取组件的属性 <template><div><h1 v-text"msg" ref"title"></h1><button ref"btn" click"showDOM">点我输出上方的DOM元素</button><MySchool ref"sch"…

浏览器扩展V3开发系列之 chrome.commands 快捷键的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.commands API 允许开发者使用快捷键来执行特定的命令。 在使用 chrome.commands API 之前必须…

【UE5.3】笔记3-静态网格体,BSP

静态网格体组件 主要有两个属性 一个是静态网格体&#xff1a;对应的也就是模型&#xff0c;比如fbx&#xff0c;maya&#xff0c;obj等格式 一个是材质&#xff1a;由各种贴图、渲染设置等&#xff0c;比如unity里的shader BSP画刷&#xff1a; 打开放置Actor选项卡&#…

【Linux详解】进程的状态 | 运行 阻塞 挂起 | 僵尸和孤儿状态

目录 操作系统中 运行状态 阻塞状态 进程状态转换 Linux系统中 查看进程状态 深度睡眠状态 T 暂停状态 Z 僵尸状态 孤儿状态 文章手稿 xmind: 引言 介绍系统中的进程状态及其管理方式。将通过结合操作系统原理和实际代码示例&#xff0c;详细说明进程的各种状态、转换…

【插件】IDEA这款插件Key Promoter X,爱到无法自拔

文章目录 为什么选择Key Promoter X&#xff1f;1. 提升开发效率2. 友好的学习曲线3. 可定制性强 安装和配置Key Promoter X1. 安装插件2. 配置插件 使用Key Promoter X个人使用体验1. 快捷键记忆2. 定制化功能3. 整体体验提升 总结 &#x1f389;欢迎来到Java学习路线专栏~探索…