改变打分方法重新计算动态规划算法比对序列

news2024/11/27 2:41:32

       📝个人主页:五敷有你      

 🔥系列专栏:算法分析与设计

⛺️稳中求进,晒太阳

动态规划

概念

  • 动态规划法离不开一个关键词,拆分 ,就是把求解的问题分解成若干个子阶段,前一问题的结果就是求解后一问题的子结构。
  • 在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。
  • 依次解决各子问题,最后一个子问题就是初始问题的解。

适用性

适用动态规划的问题必须满足最优化原理和无后效性。

最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。

将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。

解题思路

1.确定最优子结构:比如我们要求的结果F(X)的最优子结构可能为F(X-1)和F(X-2)

2.列转移方程:根据最优子结构可以列出转移方程F(X)=F(X-1)+F(X-2)

3.确定边界值:确定问题的边界,即当F(n)有可以确定的具体的值

以上概述是纯粹是为了显得官方一点,下面我们开始说人话

动态规划法

确定最优子结构——》列转移方程——》确定边界值

问题

比对两条序列:

YKRDKPHVNIGTIGHVDHGKTTLTAAITSVLAKERGITISTAHVEYQTDKRHYAHIDCPGHADYIKNDGPMPQTREHILLARQVNVPALVVFLNKVDILLELVEMELRELLTEYGFPGDDIPIIKGSALNIMELMD

IGHVDHGKTTLTAAITSVLAKERGITISTAHVIKNMITGAAQMDGAILVVAGTDGPMPQTREHILLARQVNVPALVVFLNKVDIALLELVEMELRELLTEYGFPGDDIPIIKGSALNALNEKAIMELMDAVDDYIP

比对计分策略: p (a, a) = 1 p (a, b) = 0 a != b p (a, -) = p ( -, b) = -1

实验要求:

运行动态规划算法程序,分析四种打分方法的运行结果。

总源码:

# 应用动态规划算法计算比对,得到最佳得分,输出比对序列
# 匹配4,不匹配0,空位-1
def compare(seq_1: str, seq_2: str) -> tuple:
    ############################
    """
    传入两条序列,进行动态规划并返回结果矩阵
    Args:
        seq_1: 序列1
        seq_2: 序列2

    Returns:
        list_score, list_route:包含得分及路线矩阵的元组
    """
    ############################

    list_route = [[] for i in range(len(seq_1) + 1)]  # 路线记录矩阵
    list_score = [[] for i in range(len(seq_1) + 1)]  # 得分矩阵

# 1 表示当前位置的最优比对路径来源于对角线方向,即 seq_1 和 seq_2 在这个位置匹配。
# 2 表示当前位置的最优比对路径来源于上方,即 seq_1 在这个位置与空位匹配。
# 3 表示当前位置的最优比对路径来源于左侧,即 seq_2 在这个位置与空位匹配。

    # 初始化得分矩阵
    for row in range(0, len(seq_2) + 1):
        for col in range(0, len(seq_1) + 1):

            # 在这个特殊情况下,开头的缺失往往有不同的惩罚值,这取决于具体的应用场景和算法设计。
            # 在这个代码中,缺失的惩罚值为 -1,表示每引入一个空位扣除1分。


            # 表示将seq_2与空位比对的得分。
            # 在这个特殊的情况下,第一列的得分矩阵用于表示seq_2中的每个字符与空位之间的比对得分。
            # 比对得分是负值,每向下移动一行,得分减小,表示引入了一个空位。
            if col == 0:
                # 第一列的所有数据都引入一个空位 p (a, -) = p ( -, b) = -1
                list_score[row].append(-row)
                # 第一列的所有数据都来自上面
                list_route[row].append(2)

            # 表示将seq_1与空位比对的得分。
            # 同样,第一行的得分矩阵用于表示seq_1中的每个字符与空位之间的比对得分。
            # 比对得分同样是负值,每向右移动一列,得分减小,表示引入了一个空位
            elif row == 0:
                list_score[0].append(-col)
                list_route[0].append(3)


            else:
                # 对于不匹配的情况,将得分矩阵的相应位置设置为0。,先是默认全是0
                # 二位矩阵的[row][col]添加0
                list_score[row].append(0)
                list_route[row].append(0)

    # 开始计算得分和路径
    vacancy = -1                    #vacancy空缺就开始惩罚 p(a, -) = p( -, b) = -1
    for row in range(1, len(seq_2) + 1):
        for col in range(1, len(seq_1) + 1):
            if seq_1[col - 1] == seq_2[row - 1]:
                temp = 1            # p(a, a) = 4
            else:
                temp = 0            # p(a, b) = 0      a != b
            #    打分
            score = list_score[row - 1][col - 1] + temp

            if score >= list_score[row - 1][col] + vacancy and score >= list_score[row][col - 1] + vacancy:
                list_score[row][col] = score
                # 得分来自斜对面
                list_route[row][col] = 1

            # 表示从上方的位置引入一个空位,并且计算得分。
            elif list_score[row - 1][col] >= list_score[row][col - 1]:
                list_score[row][col] = list_score[row - 1][col] + vacancy
                # 得分来自上面
                list_route[row][col] = 2
            # 表示从左方的位置引入一个空位,并且计算得分。
            else:
                list_score[row][col] = list_score[row][col - 1] + vacancy
                # 得分来自上面左边
                list_route[row][col] = 3

    return list_score, list_route


def output(seq_1: str, seq_2: str, score: list, route: list) -> None:
    ##########################
    """
    根据传入的数据输出最佳得分和比对序列结果
    Args:
        seq_1: 序列1
        seq_2: 序列2
        score: 得分矩阵
        route: 路线矩阵

    Returns:
        None
    """
    ##########################
    # 在这个上下文中,align_1 和 align_2 是用来表示比对序列的字符串。这两个字符串的构建是通过动态规划算法的回溯过程获得的,用来展示两个输入序列在比对中的对应关系。
    # 这两个字符串的构建是通过动态规划算法回溯的过程中的选择和记录,最终呈现出了比对的结果。在比对结果中,这两个字符串的相应位置表示对应序列的匹配或空位。



    # align_1:表示比对后的第一个序列。在比对中,可能会有空位('-')和与另一个序列匹配的字符。这个字符串记录了第一个序列在比对中的情况。
    align_1 = ""
    # align_2:表示比对后的第二个序列。同样,可能包含空位和与另一个序列匹配的字符。这个字符串记录了第二个序列在比对中的情况。
    align_2 = ""


    # locate 是用来表示比对序列中的匹配和不匹配的标记字符串。
    # 在 output 函数中,locate 的构建是通过比对 align_1 和 align_2 中的字符来判断是否匹配。
    # 如果两个字符相同,就用 "|" 表示匹配,否则用空格表示不匹配。
    locate = ""

    row = len(seq_2)
    col = len(seq_1)
    best = score[row][col]

    while True:
        if row == 0 and col == 0:
            break

        #如果 list_route[row][col] 的值为 1,说明当前位置的最优路径来源于对角线,即 seq_1 和 seq_2 在这个位置匹配。
        # 因此,在比对序列 align_1 和 align_2 的过程中,将当前位置的字符添加到两个序列中,并向左上角移动一步。
        if route[row][col] == 1:
            align_1 += seq_2[row - 1]
            align_2 += seq_1[col - 1]
            row -= 1
            col -= 1
        # 如果 list_route[row][col] 的值为 2,说明当前位置的最优路径来源于上方,即 seq_1 在这个位置与空位匹配。
        # 在比对序列的过程中,将当前位置的 seq_2 中的字符添加到 align_1 中,同时在 align_2 中添加一个空位('-'),然后向上移动一步。
        elif route[row][col] == 2:
            align_1 += seq_2[row - 1]
            align_2 += "-"
            row -= 1
        # best的前驱是左角
        # 如果list_route[row][col]的值为3,说明当前位置的最优路径来源于左侧,即seq_2在这个位置与空位匹配。
        # 在比对序列的过程中,将当前位置的seq_1中的字符添加到align_2中,同时在align_1中添加一个空位('-'),然后向左移动一步。
        else:
            align_1 += "-"
            align_2 += seq_1[col - 1]
            col -= 1


    # 这是在进行对比 好看
    for index in range(0, len(align_1)):
        if align_1[index] == align_2[index]:
            locate += "|"
        else:
            locate += " "
    # 输出结果
    print(f"The best score is: {best}")
    print(f"Alignment sequences:")
    print(f"{align_2[::-1]}\n{locate[::-1]}\n{align_1[::-1]}")



# Main Program
fir_seq = "YKRDKPHVNIGTIGHVDHGKTTLTAAITSVLAKERGITISTAHVEYQTDKRHYAHIDCPGHADYIKNDGPMPQTREHILLARQVNVPALVVFLNKVDILLELVEMELRELLTEYGFPGDDIPIIKGSALNIMELMD"
sec_seq = "IGHVDHGKTTLTAAITSVLAKERGITISTAHVIKNMITGAAQMDGAILVVAGTDGPMPQTREHILLARQVNVPALVVFLNKVDIALLELVEMELRELLTEYGFPGDDIPIIKGSALNALNEKAIMELMDAVDDYIP"
result = compare(fir_seq, sec_seq)
output(fir_seq, sec_seq, result[0], result[1])

第一部分代码

def compare(seq_1: str, seq_2: str) -> tuple:
   #####################
    """
    传入两条序列,进行动态规划并返回结果矩阵
    Args:
        seq_1: 序列1
        seq_2: 序列2

    Returns:
        list_score, list_route:包含得分及路线矩阵的元组
    """
    #####################
    
    #为二位数组申请空间
    list_route = [[] for i in range(len(seq_1) + 1)]  # 路线记录矩阵
    list_score = [[] for i in range(len(seq_1) + 1)]  # 得分矩阵

# 1 表示当前位置的最优比对路径来源于对角线方向,即 seq_1 和 seq_2 在这个位置匹配。
# 2 表示当前位置的最优比对路径来源于上方,即 seq_1 在这个位置与空位匹配。
# 3 表示当前位置的最优比对路径来源于左侧,即 seq_2 在这个位置与空位匹配。

    # 初始化得分矩阵
    for row in range(0, len(seq_2) + 1):
        for col in range(0, len(seq_1) + 1):
            
            if col == 0:
                #第一列的所有数据每引入一个空位罚分-1 p (a, -) = p ( -, b) = -1
                list_score[row].append(-row)
                  #第一列的所有数据都来自上面
                list_route[row].append(2)
            elif row == 0:
                #第一行的所有数据来自左边,每引入一个空位罚分 -1
                list_score[0].append(-col)
                list_route[0].append(3)
            else:
                #0 暂时做一个占位符
                list_score[row].append(0)
                list_route[row].append(0)

运行到这的结果是如下

接下来开始计算得分与路径


    # 开始计算得分和路径
    vacancy = -1                    #vacancy空位就开始惩罚 p(a, -) = p( -, b) = -1
    for row in range(1, len(seq_2) + 1):
        for col in range(1, len(seq_1) + 1):
            if seq_1[col - 1] == seq_2[row - 1]:
                temp = 4            # p(a, a) = 4
            else:
                temp = 0            # p(a, b) = 0      a != b
            #    打分
            score = list_score[row - 1][col - 1] + temp

            if score >= list_score[row - 1][col] + vacancy and score >= list_score[row][col - 1] + vacancy:
                list_score[row][col] = score
                # 得分来自斜对面
                list_route[row][col] = 1

            # 表示从上方的位置引入一个空位,并且计算得分。
            elif list_score[row - 1][col] >= list_score[row][col - 1]:
                list_score[row][col] = list_score[row - 1][col] + vacancy
                # 得分来自上面
                list_route[row][col] = 2
            # 表示从左方的位置引入一个空位,并且计算得分。
            else:
                list_score[row][col] = list_score[row][col - 1] + vacancy
                # 得分来自上面左边
                list_route[row][col] = 3

    return list_score, list_route

结果如下:

开始回溯构建align_1 和 align_2

他们 是用来表示比对序列的字符串。这两个字符串的构建是通过动态规划算法的回溯过程获得的,用来展示两个输入序列在比对中的对应关系。

  • align_1:表示比对后的第一个序列。在比对中,可能会有空位('-')和与另一个序列匹配的字符。这个字符串记录了第一个序列在比对中的情况。
  • align_2:表示比对后的第二个序列。同样,可能包含空位和与另一个序列匹配的字符。这个字符串记录了第二个序列在比对中的情况。

这两个字符串的构建是通过动态规划算法回溯的过程中的选择和记录,最终呈现出了比对的结果。在比对结果中,这两个字符串的相应位置表示对应序列的匹配或空位

def output(seq_1: str, seq_2: str, score: list, route: list) -> None:
    ##########################
    """
    根据传入的数据输出最佳得分和比对序列结果
    Args:
        seq_1: 序列1
        seq_2: 序列2
        score: 得分矩阵
        route: 路线矩阵

    Returns:
        None
    """
    ##########################
    
    align_1 = ""
    align_2 = ""
    locate = ""
    row = len(seq_2)
    col = len(seq_1)
    best = score[row][col]
    while True:
        if row == 0 and col == 0:
            break

        #如果 list_route[row][col] 的值为 1,说明当前位置的最优路径来源于对角线,即 seq_1 和 seq_2 在这个位置匹配。
        # 因此,在比对序列 align_1 和 align_2 的过程中,将当前位置的字符添加到两个序列中,并向左上角移动一步。
        if route[row][col] == 1:
            align_1 += seq_2[row - 1]
            align_2 += seq_1[col - 1]
            row -= 1
            col -= 1
        # 如果 list_route[row][col] 的值为 2,说明当前位置的最优路径来源于上方,即 seq_1 在这个位置与空位匹配。
        # 在比对序列的过程中,将当前位置的 seq_2 中的字符添加到 align_1 中,同时在 align_2 中添加一个空位('-'),然后向上移动一步。
        elif route[row][col] == 2:
            align_1 += seq_2[row - 1]
            align_2 += "-"
            row -= 1
      
        # 如果list_route[row][col]的值为3,说明当前位置的最优路径来源于左侧,即seq_2在这个位置与空位匹配。
        # 在比对序列的过程中,将当前位置的seq_1中的字符添加到align_2中,同时在align_1中添加一个空位('-'),然后向左移动一步。
        else:
            align_1 += "-"
            align_2 += seq_1[col - 1]
            col -= 1

构建locate

locate 是用来表示比对序列中的匹配和不匹配的标记字符串。在 output 函数中,locate 的构建是通过比对 align_1 和

align_2 中的字符来判断是否匹配。如果两个字符相同,就用 "|" 表示匹配,否则用空格表示不匹配。

# 这是在进行对比 好看

# 这是在进行对比 好看
for index in range(0, len(align_1)):
    if align_1[index] == align_2[index]:
        locate += "|"
    else:
        locate += " "

输出结果即可

# 输出结果
print(f"The best score is: {best}")
print(f"Alignment sequences:")
print(f"{align_2[::-1]}\n{locate[::-1]}\n{align_1[::-1]}")

可能遇到的问题

为什么每向下移动一行,得分减小

在这个动态规划比对算法中,得分矩阵的初始化是为了考虑序列的开头与空位(gap)之间的比对得分。具体来说,得分矩阵的第一列对应着将 seq_2 与空位比对的得分。

比对下面的逻辑:

  1. 匹配:

当序列中的字符匹配时,得分增加。在这个算法中,匹配的得分为4,因此对角线方向的得分会比上方或左方高。

  1. 缺失(引入空位):

当序列中的字符与空位匹配时,得分减小。在这个算法中,引入空位的惩罚值为-1,因此每引入一个空位,得分就减小1。

所以,得分矩阵的第一列是为了表示 seq_2 中的每个字符与空位之间的比对得分。由于引入了空位,因此每向下移动一行,就意味着在 seq_2 中引入了一个空位,从而得分减小。这种初始化反映了在比对序列的开头时引入空位的惩罚,因为通常在序列的开头引入空位可能导致整体比对得分下降。

结果分析

1.        The best score is: 75

  • 这里的 "75" 是比对的最佳得分。在你的比对算法中,得分是根据匹配和不匹配的规则计算得出的。这个得分表示在最优比对路径下,两个序列之间的相似性。

2.Alignment sequences:

  • 这部分显示了两个比对的序列,其中 "-" 表示引入了空位。
    • align_1
    • align_2

3.“ | ”

  • 这一行是比对序列的标记,"|" 表示对应的位置上,两个序列的字符是匹配的。

所以,这个比对的结果告诉你,通过引入空位,"YKRDKP" 和 "IGHVDH" 在某些位置上可以比对,而得分为2是在最优路径下的相似性得分。比对的结果表明,在比对的过程中,第一个序列中的字符 "Y" 与第二个序列中的字符 "I" 不匹配,并且在 "IGHVD-H" 的比对序列中引入了一个空位。

最佳得分概念、总长度,序列长度,

"最佳得分" 是比对算法计算的最优比对的得分,表示两个序列之间的相似性。

  • "总长度" 是指比对后的序列总长度。这个总长度包括了引入的空位以及匹配的字符。
  • "序列长度" 则是原始未比对的两个输入序列中较长的那个的长度。这个值是不变的,因为它只考虑了原始序列的长度而不考虑比对。

在比对过程中,为了使两个序列对齐,可能需要在某些位置引入空位。这就导致了比对后的序列长度会大于原始序列的长度。在你的结果中,"引入空位" 的值为 16,表示在比对的过程中引入了16个空位,因此 "总长度" 为 "序列长度" 加上引入的空位数。

同时, "匹配数目" 为 105,表示在比对的过程中有105个位置的字符是匹配的。这些匹配的字符会占据 "总长度" 的一部分。

结果

为什么斜着走也开空位了没有惩罚?

因为斜着走没有引入空位,下面这段代码在进行总长度的序列拼接时并没有引入空位

#如果 list_route[row][col] 的值为 1,说明当前位置的最优路径来源于对角线,即 seq_1 和 seq_2 在这个位置匹配。
# 因此,在比对序列 align_1 和 align_2 的过程中,将当前位置的字符添加到两个序列中,并向左上角移动一步。
if route[row][col] == 1:
    align_1 += seq_2[row - 1]
    align_2 += seq_1[col - 1]
    row -= 1
    col -= 1

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

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

相关文章

算法学习——LeetCode力扣动态规划篇9

算法学习——LeetCode力扣动态规划篇9 1035. 不相交的线 1035. 不相交的线 - 力扣(LeetCode) 描述 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#x…

人工智能轨道交通行业周刊-第76期(2024.3.18-3.31)

本期关键词:铁科智合、信号机、列车供电方式、Voice Engine、3D数字人 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道世界铁路那…

spring-boot. 结合redis 实现消息队列

导入依赖jar包 <!-- redis 配置信息--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> 实现消息监听接口 MessageListener\重写 onMessa…

发票是扫码验真好,还是OCR后进行验真好?

随着科技的进步&#xff0c;电子发票的普及使得发票的验真方式也在不断演进。目前&#xff0c;我们常见的发票验真方式主要有两种&#xff1a;一种是扫描发票上的二维码进行验真&#xff0c;另一种是通过OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别…

【Canvas与艺术】双齿轮啮合传动

【关键点】 双轮半径和线速度的比例以及差角的调试。 【截图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>大小齿轮联动…

ES6学习(四)

文章目录 1. Reflect1.1 代替Object 的某些方法1.2 修改某些Object 方法返回结果1.3 命令式变为函数行为1.4 ! 配合Proxy 2. ! Promise2.1 回调地狱2.2 Promise 使用2.3 Promise 对象的状态2.4 解决回调地狱的方法2.5 Promise.all2.6 Promise.race 3. Generator 函数3.1 基本语…

推荐一本牛逼的入门 Python书!,如何试出一个Python开发者真正的水平

本书详细解说了 Python 语言和编程的本质&#xff0c;无论你是否接触过编程语言&#xff0c;只要是 Python 编程的初学者&#xff0c;都可阅读本书。 本书讲解的内容虽然基础&#xff0c;但并不简单。本书提供了 165 幅图表&#xff0c;可以让大家能够轻松地理解并掌握复杂的概…

超强命令行解析工具Apache Commons CLI

概述 为什么要写这篇文章呢?因为在读flink cdc3.0源码的时候发现了这个工具包,感觉很牛,之前写过shell命令,shell是用getopts来处理命令行参数的,但是其实写起来很麻烦,长时间不写已经完全忘记了,现在才发现原来java也有这种工具类,所以先学习一下这个的使用,也许之后自己在写…

创建第一个Electron程序

前置准备 创建一个文件夹&#xff0c;如: electest进入文件夹&#xff0c;初始化npm npm init -y 安装electron依赖包 注&#xff0c;这里使用npm i -D electron会特别卡&#xff0c;哪怕换成淘宝源也不行。可以使用下面方式安装。 首先&#xff0c;安装yarn npm i -g yarn 随…

CrossOver软件2024免费 最新版本详细介绍 CrossOver软件好用吗 Mac电脑玩Windows游戏

CrossOver是一款由CodeWeavers公司开发的软件&#xff0c;它可以在Mac和Linux等操作系统上运行Windows软件&#xff0c;而无需在计算机上安装Windows操作系统。这款软件的核心技术是Wine&#xff0c;它是一种在Linux和macOS等操作系统上运行Windows应用程序的开源软件。 Cross…

html第二次作业

骨架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initi…

中间件安全(apache、tomcat)

靶场&#xff1a; vulfocus Apache Apache HTTP Server 是美国阿帕奇&#xff08; Apache &#xff09;基金会的一款开源网页服务器。该服务器具有快速、可靠且可通过简单的API进行扩充的特点&#xff0c;发现 Apache HTTP Server 2.4.50 中针对 CVE - 2021 - 41773 的修复…

云服务器4核8G配置优惠价格表,买一年送3个月,12M公网带宽

腾讯云轻量4核8G12M服务器优惠价格646元15个月&#xff0c;买一年送3个月&#xff0c;配置为轻量4核8G12M、180GB SSD盘、2000GB月流量、12M带宽&#xff0c;腾讯云优惠活动页面 yunfuwuqiba.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器租用价格 腾讯云&…

Kafka入门到实战-第五弹

Kafka入门到实战 Kafka常见操作官网地址Kafka概述Kafka的基础操作更新计划 Kafka常见操作 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://kafka.apache.org/Kafka概述 Apache Kafka 是一个开源的分布式事件流平台&…

网络编程的实际案例

实现将英文转化称为中文 想在服务器和客户端中实现这一功能&#xff0c;在响应阶段做出让传进来的英文返回中文。需要定义一个HashMap类型来存储其可能输入进来的英文和将要返回的中文。 UDP中建立 UDP建立的细节在上一次写的博客当中 import java.io.IOException; import …

算法学习——LeetCode力扣补充篇1

算法学习——LeetCode力扣补充篇1 1365. 有多少小于当前数字的数字 1365. 有多少小于当前数字的数字 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个数组 nums&#xff0c;对于其中每个元素 nums[i]&#xff0c;请你统计数组中比它小的所有数字的数目。 换而言之&a…

大数据 - Spark系列《十五》- spark架构

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 大数据 - Spark系列《…

技巧 Win10电脑打开SMB协议共享文件,手机端查看

一. 打开 SMB1.0/CIFS文件共享支持 ⏹如下图所示&#xff0c;打开SMB1.0/CIFS文件共享支持 二. 开启网络发现 ⏹开启网络发现&#xff0c;确保共享的文件能在局域网内被发现 三. 共享文件夹到局域网 ⏹根据需要勾选需要共享的文件夹&#xff0c;共享到局域网 四. 共享文件查…

2024.3.26学习总结

一&#xff0c;正则匹配 正则匹配是用来搜索&#xff0c;匹配&#xff0c;替换的一种字符串模式&#xff0c;使用正则匹配可以让搜索匹配的语句更加简洁&#xff0c;在php中会使用一些函数来处理正则匹配 常用的语法&#xff1a; 字符类 [abc]: 匹配单个字符a、b或c[^abc]: 匹…

java的抽象类和接口

抽象类&#xff1a; abstract,可以用此关键字修饰类和方法 abstract修饰类就是抽象类&#xff0c;修饰方法就是抽象方法 抽象类的注意事项&#xff0c;特点&#xff1a;抽象类不一定有抽象方法&#xff0c;但有抽象方法的类一定是抽象类 类该有的成员&#xff08;成员变量&…