代码随想录day56|583. 两个字符串的删除操作|72. 编辑距离|编辑距离总结篇|Golang

news2024/11/20 15:34:44

代码随想录day56

考试周了解一下

目录

代码随想录day56

583. 两个字符串的删除操作

72. 编辑距离

动态规划之编辑距离总结篇


583. 两个字符串的删除操作

 

思路

动态规划一

        本题和动态规划:115.不同的子序列相比,其实就是两个字符串都可以删除了,情况虽说复杂一些,但整体思路是不变的。

        这次是两个字符串可以相互删了,这种题目也知道用动态规划的思路来解,动规五部曲,分析如下:

1、确定dp数组以及下标的含义

        dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。

        这里dp数组的定义有点点绕,大家要撸清思路。

2、确定递推公式

  • 当word1[i - 1] 与 word2[j - 1]相同的时候
  • 当word1[i - 1] 与 word2[j - 1]不相同的时候

当word1[i - 1] 与 word2[j - 1]相同的时候,dp[i][j] = dp[i - 1][j - 1];

当word1[i - 1] 与 word2[j - 1]不相同的时候,有三种情况:

情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1

情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1

情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2

        那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});

        因为dp[i - 1][j - 1] + 1等于 dp[i - 1][j] 或 dp[i][j - 1],所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);

3、dp数组如何初始化

        从递推公式中,可以看出来,dp[i][0] 和 dp[0][j]是一定要初始化的。

        dp[i][0]:word2为空字符串,以i-1为结尾的字符串word1要删除多少个元素,才能和word2相同呢,很明显dp[i][0] = i。

dp[0][j]的话同理,所以代码如下:

vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;

4、确定遍历顺序

        从递推公式 dp[i][j] = min(dp[i - 1][j - 1] + 2, min(dp[i - 1][j], dp[i][j - 1]) + 1); 和dp[i][j] = dp[i - 1][j - 1]可以看出dp[i][j]都是根据左上方、正上方、正左方推出来的。

        所以遍历的时候一定是从上到下,从左到右,这样保证dp[i][j]可以根据之前计算出来的数值进行计算。

5、举例推导dp数组

        以word1:"sea",word2:"eat"为例,推导dp数组状态图如下:

 以上分析完毕,代码如下:

func minDistance(word1 string, word2 string) int {
	dp := make([][]int, len(word1)+1)
	for i := 0; i < len(dp); i++ {
		dp[i] = make([]int, len(word2)+1)
	}
	//初始化
	for i := 0; i < len(dp); i++ {
		dp[i][0] = i
	}
	for j := 0; j < len(dp[0]); j++ {
		dp[0][j] = j
	}
	for i := 1; i < len(dp); i++ {
		for j := 1; j < len(dp[i]); j++ {
			if word1[i-1] == word2[j-1] {
				dp[i][j] = dp[i-1][j-1]
			} else {
				dp[i][j] = min(min(dp[i-1][j]+1, dp[i][j-1]+1), dp[i-1][j-1]+2)
			}
		}
	}
	return dp[len(dp)-1][len(dp[0])-1]
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

72. 编辑距离

         编辑距离终于来了,这道题目如果大家没有了解动态规划的话,会感觉超级复杂。

        编辑距离是用动规来解决的经典题目,这道题目看上去好像很复杂,但用动规可以很巧妙的算出最少编辑距离。

接下来我依然使用动规五部曲,对本题做一个详细的分析:

1. 确定dp数组(dp table)以及下标的含义

        dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]

        这里在强调一下:为啥要表示下标i-1为结尾的字符串呢,为啥不表示下标i为结尾的字符串呢?        

        用i来表示也可以! 但我统一以下标i-1为结尾的字符串,在下面的递归公式中会容易理解一点。

2. 确定递推公式

        在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:

if (word1[i - 1] == word2[j - 1])
    不操作
if (word1[i - 1] != word2[j - 1])
    增
    删
    换

也就是如上4种情况。

        if (word1[i - 1] == word2[j - 1]) 那么说明不用任何编辑,dp[i][j] 就应该是 dp[i - 1][j - 1],即dp[i][j] = dp[i - 1][j - 1];

        此时可能有同学有点不明白,为啥要即dp[i][j] = dp[i - 1][j - 1]呢?

        那么就在回顾上面讲过的dp[i][j]的定义,word1[i - 1]word2[j - 1]相等了,那么就不用编辑了,以下标i-2为结尾的字符串word1和以下标j-2为结尾的字符串word2的最近编辑距离dp[i - 1][j - 1]就是 dp[i][j]了。

在下面的讲解中,如果哪里看不懂,就回想一下dp[i][j]的定义,就明白了。

在整个动规的过程中,最为关键就是正确理解dp[i][j]的定义!

if (word1[i - 1] != word2[j - 1]),此时就需要编辑了,如何编辑呢?

        操作一:word1删除一个元素,那么就是以下标i - 2为结尾的word1 与 j-1为结尾的word2的最近编辑距离 再加上一个操作。

        dp[i][j] = dp[i - 1][j] + 1;

        操作二:word2删除一个元素,那么就是以下标i - 1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 再加上一个操作。

                 dp[i][j] = dp[i][j - 1] + 1;

这里有同学发现了,怎么都是删除元素,添加元素去哪了。

word2添加一个元素,相当于word1删除一个元素,例如 word1 = "ad" ,word2 = "a"word1删除元素'd'word2添加一个元素'd',变成word1="a", word2="ad", 最终的操作数是一样! dp数组如下图所示意的:

            a                         a     d
   +-----+-----+             +-----+-----+-----+
   |  0  |  1  |             |  0  |  1  |  2  |
   +-----+-----+   ===>      +-----+-----+-----+
 a |  1  |  0  |           a |  1  |  0  |  1  |
   +-----+-----+             +-----+-----+-----+
 d |  2  |  1  |
   +-----+-----+

操作三:替换元素,word1替换word1[i - 1],使其与word2[j - 1]相同,此时不用增加元素,那么以下标i-2为结尾的word1j-2为结尾的word2的最近编辑距离 加上一个替换元素的操作。

        即 dp[i][j] = dp[i - 1][j - 1] + 1;

递归公式代码如下

if (word1[i - 1] == word2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1];
}
else {
    dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;
}

3. dp数组如何初始化

        再回顾一下dp[i][j]的定义:

        dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j]

        那么dp[i][0] 和 dp[0][j] 表示什么呢?

dp[i][0] :以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]。

那么dp[i][0]就应该是i,对word1里的元素全部做删除操作,即:dp[i][0] = i;

同理dp[0][j] = j;

所以C++代码如下:

for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;

4. 确定遍历顺序

从如下四个递推公式:

  • dp[i][j] = dp[i - 1][j - 1]
  • dp[i][j] = dp[i - 1][j - 1] + 1
  • dp[i][j] = dp[i][j - 1] + 1
  • dp[i][j] = dp[i - 1][j] + 1

可以看出dp[i][j]是依赖左方,上方和左上方元素的,如图:

所以在dp矩阵中一定是从左到右从上到下去遍历。 

for (int i = 1; i <= word1.size(); i++) {
    for (int j = 1; j <= word2.size(); j++) {
        if (word1[i - 1] == word2[j - 1]) {
            dp[i][j] = dp[i - 1][j - 1];
        }
        else {
            dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;
        }
    }
}

5. 举例推导dp数组

以示例1为例,输入:word1 = "horse", word2 = "ros"为例,dp矩阵状态图如下:

 

func minDistance(word1 string, word2 string) int {
	m, n := len(word1), len(word2)
	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}
    for i:=0;i<m+1;i++{
        dp[i][0] = i    // word1[i] 变成word2[0],删除word1[i]需要i步操作
    }
    for j:=0;j<n+1;j++{
        dp[0][j] = j    // word1[0] 变成word2[j], 插入word1[j]需要j步操作
    }
    for i:=1;i<m+1;i++{
        for j:=1;j<n+1;j++{
            if word1[i-1] == word2[j-1] {
                dp[i][j] = dp[i-1][j-1] 
            } else {    // min(插入、删除、替换)
				dp[i][j] = Min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + 1
            }
        }
    }
    return dp[m][n]
}
func Min(args ...int) int {
	min := args[0]
	for _, item := range args {
		if item < min {
			min = item
		}
	}
	return min
}

动态规划之编辑距离总结篇

本周我们讲了动态规划之终极绝杀:编辑距离,为什么叫做终极绝杀呢?

细心的录友应该知道,我们在前三篇动态规划的文章就一直为 编辑距离 这道题目做铺垫

判断子序列

动态规划:392.判断子序列给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

这道题目 其实是可以用双指针或者贪心的的,但是我在开篇的时候就说了这是编辑距离的入门题目,因为从题意中我们也可以发现,只需要计算删除的情况,不用考虑增加和替换的情况。

  • if (s[i - 1] == t[j - 1])
    • t中找到了一个字符在s中也出现了
  • if (s[i - 1] != t[j - 1])
    • 相当于t要删除元素,继续匹配

状态转移方程:

if (s[i - 1] == t[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1] + 1
} else {
    dp[i][j] = dp[i][j - 1]
}

不同的子序列

动态规划:115.不同的子序列给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。本题虽然也只有删除操作,不用考虑替换增加之类的,但相对于动态规划:392.判断子序列

就有难度了,这道题目双指针法可就做不了。

当s[i - 1] 与 t[j - 1]相等时,dp[i][j]可以有两部分组成。

一部分是用s[i - 1]来匹配,那么个数为dp[i - 1][j - 1]。

一部分是不用s[i - 1]来匹配,个数为dp[i - 1][j]。

这里可能有同学不明白了,为什么还要考虑 不用s[i - 1]来匹配,都相同了指定要匹配啊。

例如: s:bagg 和 t:bag ,s[3] 和 t[2]是相同的,但是字符串s也可以不用s[3]来匹配,即用s[0]s[1]s[2]组成的bag。

当然也可以用s[3]来匹配,即:s[0]s[1]s[3]组成的bag。

所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配,即:dp[i - 1][j]

所以递推公式为:dp[i][j] = dp[i - 1][j];

状态转移方程:

if (s[i - 1] == t[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
} else {
    dp[i][j] = dp[i - 1][j];
}

两个字符串的删除操作

      动态规划:583.两个字符串的删除操作给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。
        本题和动态规划:115.不同的子序列相比,其实就是两个字符串可以都可以删除了,情况虽说复杂一些,但整体思路是不变的。

  • 当word1[i - 1] 与 word2[j - 1]相同的时候
  • 当word1[i - 1] 与 word2[j - 1]不相同的时候

当word1[i - 1] 与 word2[j - 1]相同的时候,dp[i][j] = dp[i - 1][j - 1];

当word1[i - 1] 与 word2[j - 1]不相同的时候,有三种情况:

情况一:删word1[i - 1],最少操作次数为dp[i - 1][j] + 1

情况二:删word2[j - 1],最少操作次数为dp[i][j - 1] + 1

情况三:同时删word1[i - 1]和word2[j - 1],操作的最少次数为dp[i - 1][j - 1] + 2

那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});

状态转移方程:

if (word1[i - 1] == word2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1];
} else {
    dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});
}

编辑距离

动态规划:72.编辑距离

        给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。

编辑距离终于来了,有了前面三道题目的铺垫,应该有思路了,本题是两个字符串可以增删改,比 动态规划:判断子序列

,动态规划:不同的子序列,动态规划:两个字符串的删除操作都要复杂的多

在确定递推公式的时候,首先要考虑清楚编辑的几种操作,整理如下:

  • if (word1[i - 1] == word2[j - 1])
    • 不操作
  • if (word1[i - 1] != word2[j - 1])

也就是如上四种情况。

if (word1[i - 1] == word2[j - 1]) 那么说明不用任何编辑,dp[i][j] 就应该是 dp[i - 1][j - 1],即dp[i][j] = dp[i - 1][j - 1];

此时可能有同学有点不明白,为啥要即dp[i][j] = dp[i - 1][j - 1]呢?

那么就在回顾上面讲过的dp[i][j]的定义,word1[i - 1] 与 word2[j - 1]相等了,那么就不用编辑了,以下标i-2为结尾的字符串word1和以下标j-2为结尾的字符串word2的最近编辑距离dp[i - 1][j - 1] 就是 dp[i][j]了。

在下面的讲解中,如果哪里看不懂,就回想一下dp[i][j]的定义,就明白了。

在整个动规的过程中,最为关键就是正确理解dp[i][j]的定义!

if (word1[i - 1] != word2[j - 1]),此时就需要编辑了,如何编辑呢?

操作一:word1增加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-2为结尾的word1 与 i-1为结尾的word2的最近编辑距离 加上一个增加元素的操作。

即 dp[i][j] = dp[i - 1][j] + 1;

操作二:word2添加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个增加元素的操作。

即 dp[i][j] = dp[i][j - 1] + 1;

这里有同学发现了,怎么都是添加元素,删除元素去哪了。

word2添加一个元素,相当于word1删除一个元素,例如 word1 = "ad" ,word2 = "a",word2添加一个元素d,也就是相当于word1删除一个元素d,操作数是一样!

操作三:替换元素,word1替换word1[i - 1],使其与word2[j - 1]相同,此时不用增加元素,那么以下标i-2为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个替换元素的操作。

即 dp[i][j] = dp[i - 1][j - 1] + 1;

综上,当 if (word1[i - 1] != word2[j - 1]) 时取最小的,即:dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;

递归公式代码如下:

if (word1[i - 1] == word2[j - 1]) {
    dp[i][j] = dp[i - 1][j - 1];
}
else {
    dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;
}

总结

心思的录友应该会发现我用了三道题做铺垫,才最后引出了动态规划:72.编辑距离

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

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

相关文章

2023职教高考报名开启,报考人数继续增加

进入11月起&#xff0c;各地区2023年职教高考报名已经陆续开始&#xff0c;报考考生主要以中职学校学生为主。根据南京日报的报道&#xff0c;11月1日就启动的江苏省职教高考报名&#xff0c;吸引了不少家长和学生的关注&#xff0c;有些专业的报名人数已经比2022年翻了不止一倍…

Flutter Hooks — 快速了解

Flutter Hooks — 快速了解 前言 Hooks,直译过来就是"钩子"&#xff0c;是前端 React 框架加入的特性&#xff0c;用来分离状态逻辑和视图逻辑。现在这个特性并不只局限在于 React 框架中&#xff0c;其它前端框架也在借鉴。 我们都知道在 FLutter 开发中的一大痛点就…

图解 | 监控系统 Prometheus 的原理

本篇将会以图解的方式剖析 Prometheus 的原理。本文主要内容如下&#xff1a; 一、Prometheus 是什么&#xff1f; ELK Stack 日志收集和检索平台想必大家应该比较熟悉&#xff0c;Elasticsearch Filebeat Logstash Kibana。 ELK 架构 而 Prometheus 就相当于一整个 ELK&a…

功率放大器的主要指标有哪些呢

功率放大器是电子测量行业比较常见的能够放大信号源电压信号的仪器&#xff0c;虽然功率放大器的应用十分广泛&#xff0c;但是很多人对于功率放大器的主要指标参数还不了解&#xff0c;就让安泰电子来为大家介绍功率放大器的主要指标。 功率放大器的核心参数指标包括带宽、电压…

python多线程返回值问题重写Thread类的run方法

python多线程使用 文章目录python多线程使用一、案例二、说明1、针对第一种是有返回值的 &#xff0c;可以通过future.result() 去拿到每个线程返回值2、无返回值问题3、我们可以重写这个Thread类重写了__init__、run方法和join方法&#xff0c;主要是start()涉及的方法太多了而…

Redis篇(5)——持久化

持久化 RDB 1、save会阻塞所有命令。而bgsave则不能与其他持久化命令同时执行 2、自动rdb的发起&#xff1a;servercorn默认每100ms执行一次&#xff0c;根据redisserver里面记录的dirty&#xff08;上次save后修改的次数&#xff09;和lastsave&#xff08;上次save的时间&a…

sklearn基础篇(七)-- 随机森林(Random forest)

上一节我们提到决策树的一个主要缺点在于经常对训练数据过拟合。随机森林是解决这个问题的一种方法。随机森林是属于集成学习&#xff0c;其核心思想就是集成多个弱分类器以达到一个强分类器的效果。 1 bagging的原理 随机森林采用Bagging的思想&#xff0c;所谓的Bagging可以…

HDFS的高级功能

3.6 HDFS的高级功能 3.6.1 安全模式 安全模式&#xff08;Safemode&#xff09;是HDFS所处的一种特殊状态。处于这种状态时&#xff0c;HDFS只接受读数据请求&#xff0c;不能对文件进行写、删除等操作。安全模式是保证一个系统保密性、完整性及可使用性的一种机制&#xff0…

精彩回顾:CACTER邮件数据防泄露EDLP亮相2022世界互联网大会

2022年世界互联网大会乌镇峰会于11月11日胜利闭幕。 本届峰会是世界互联网大会国际组织成立后的首届年会&#xff0c;以“共建网络世界 共创数字未来—携手构建网络空间命运共同体”为主题&#xff0c;共设置1场全体会议和20场分论坛&#xff0c;围绕全球网络空间热点问题展开讨…

【猿创征文】Vue3 企业级优雅实战 - 组件库框架 - 6 搭建example环境

本系列已更新文章&#xff1a; 分享一个实用的 vite vue3 组件库脚手架工具&#xff0c;提升开发效率 开箱即用 yyg-cli 脚手架&#xff1a;快速创建 vue3 组件库和vue3 全家桶项目 Vue3 企业级优雅实战 - 组件库框架 - 1 搭建 pnpm monorepo Vue3 企业级优雅实战 - 组件库框架…

线程池相关总结

多线程之线程池总结 1. 概述&#xff1a; 线程池&#xff08;Thread Pool&#xff09;&#xff1a;把一个或多个线程通过统一的方式进行调度和重复使用的技术&#xff0c;统一管理&#xff0c;避免了因线程过多而带来使用上的开销和不可控。 作用&#xff1a; 降低资源消耗…

SpringBoot进阶学习(二)---配置高级

第三方bean属性绑定 在要绑定的类上添加ConfigurationProperties(prefix “”)&#xff0c;prefix为对应的配置类中的内容&#xff0c;在添加注解ConfigurationProperties时候会产生错误&#xff0c;如&#xff1a; 这时候添加依赖&#xff1a; <dependency><groupI…

计算机网络 5 - 链路层

第6章 链路层和局域网(Link Layer and LANs)6.2 差错检测 和 纠正奇偶校验校验和CRC 循环冗余校验6.3 多路访问协议信道划分 MAC协议随机存取MAC协议6.4 LAN 局域网MAC地址 和 ARP无效的MAC帧格式Ethernet 以太网交换机第6章 链路层和局域网(Link Layer and LANs) 6.2 差错检测…

H5基本开发1——(H5简单概述)

html概述 HTML是用来描述网页的一种语言 HTML指的是超文本标记语言Hyper Text Markup Language&#xff0c;是一种用于创建网页的标准标记语言 标记语言是一套标记标签markup tag HTML使用标记标签来描述网页 HTML文档的后缀名&#xff1a;.html或者.htm&#xff0c;两种后缀名…

Deep Leakage from Gradients

Summary 对于分布式学习&#xff0c;特别是相关之前共享梯度的学习&#xff0c;提出了一种攻击方式&#xff08;DLG&#xff09;。通过窃取client之间传递的梯度反推出&#xff08;也是使用机器学习迭代的方式&#xff09;原始的输入。并在图像分类、Masked Language Model方面…

代谢ADMET在线网页预测工具SwissADME 、SOMP 、BioTransformer

药物代谢(Drug Metabolism)指药物在体内多种药物代谢酶&#xff08;尤其肝药酶&#xff09;的作用下&#xff0c;化学结构发生改变的过程&#xff1b;包括分解代谢和合成代谢 1、概念 药物的代谢反应大致可以分为氧化(oxidation)、还原(reduction)、水解(hydrolysis)和结合(co…

Android 增加布局圆角功能,支持背景裁切圆角

前言 我们Android开发同学最常见、频繁画UI时会遇到有角度的布局。例如: 通常,我们都会在drawble文件夹下创建Shape.xml去实现对吧?当然这样的代码实现方式没毛病。但是,项目大了业务繁杂,工程中会出现很多此类文件,显得非常臃肿,而且不方便复用,不利于研发效率…

22、7大参数自定义线程池(核心线程数,最大核心线程数。。。拒绝策略(4种))

7大参数自定义线程池&#xff08;核心线程数&#xff0c;最大核心线程数。。。拒绝策略&#xff08;4种&#xff09;&#xff09; 第一步&#xff1a;我们首先看单例线程池的源码 第二步&#xff1a;多个固定线程的线程池源码 第三步&#xff1a;可变的线程数的线程池源码 开启…

相控阵天线(三):直线阵列低副瓣综合(切比雪夫、泰勒分布、SinZ-Z和Villeneuve分布)

目录阵列天线综合方法概述切比雪夫阵列综合泰勒阵列综合高斯分布、二项式分布、SinZ-Z和Villeneuve分布切比雪夫、泰勒和Villeneuve综合比较切比雪夫、泰勒和Villeneuve分布的口径效率比较切比雪夫综合python代码示例阵列天线综合方法概述 直线阵列天线的综合是在预先给定辐射…

C++15 ---继承2:重载与覆盖、隐藏、拷贝构造函数、赋值运算符重载、静态数据成员

一、重载与覆盖的特征 1、重载 成员函数被重载的特征: (1&#xff09;相同的范围&#xff08;在同一个类中)&#xff1b; (2&#xff09;函数名字相同&#xff1b; (3&#xff09;参数不同&#xff1b; (4&#xff09; virtual关键字可有可无。 2、覆盖 覆盖是指派生类函数…