当前位置: 首页 > news >正文

深入解析前缀和算法:原理、实现与应用

目录

深入解析前缀和算法:原理、实现与应用

引言

在计算机科学和算法设计中,前缀和(Prefix Sum)是一种简单却极其强大的技术,它能够在多个领域发挥重要作用。从数据处理到图像处理,从数值分析到并行计算,前缀和算法都展现出了其独特的价值。这种算法的核心思想是通过预处理来优化查询效率,将原本需要线性时间复杂度的查询操作降低到常数时间复杂度。

前缀和的概念最早可以追溯到数值分析中的累积和计算,但随着计算机科学的发展,它的应用范围已经大大扩展。在现代算法设计中,前缀和不仅用于优化范围求和查询,还成为解决许多复杂问题的基础构建块,如滑动窗口问题、区间查询问题、差分数组技术等。

本文将全面深入地解析前缀和算法的原理、实现细节和实际应用。我们将从基本概念出发,逐步深入到高级应用场景,并通过丰富的Python代码示例来演示如何在实际问题中应用前缀和算法。无论您是算法初学者还是经验丰富的开发者,本文都将为您提供有价值的知识和实践指导。

第一章:前缀和的基本概念

1.1 什么是前缀和?

前缀和,也称为累积和(Cumulative Sum),是一种通过预处理数组来优化区间求和查询的技术。给定一个数组 arrarrarr,其前缀和数组 prefixprefixprefix 的定义如下:

prefix[i] = \sum_{j=0}^{i} arr[j] = arr[0] + arr[1] + \cdots + arr[i]

其中 prefix[0]=arr[0]prefix[0] = arr[0]prefix[0]=arr[0]prefix[i]prefix[i]prefix[i] 表示原数组前 i+1i+1i+1 个元素的和。

1.2 前缀和的核心思想

前缀和算法的核心思想是预处理-查询模式:

  1. 预处理阶段:花费 O(n)O(n)O(n) 时间构建前缀和数组
  2. 查询阶段:每次区间求和查询只需 O(1)O(1)O(1) 时间

这种空间换时间的策略使得多次区间求和查询的总时间复杂度从 O(n×q)O(n \times q)O(n×q) 降低到 O(n+q)O(n + q)O(n+q),其中 nnn 是数组长度,qqq 是查询次数。

1.3 前缀和的性质

前缀和数组具有几个重要性质:

  1. 区间和计算:对于任意区间 [l,r][l, r][l,r],其和可以通过前缀和数组计算: sum(l, r) = prefix[r] - prefix[l-1]
    其中当 l=0l=0l=0 时,prefix[l−1]prefix[l-1]prefix[l1] 视为 0。
  2. 递推关系:前缀和数组可以通过递推关系高效构建: prefix[i] = prefix[i-1] + arr[i]
  3. 单调性:如果原数组所有元素非负,则前缀和数组是单调递增的。

第二章:前缀和的基本实现

2.1 一维前缀和

一维前缀和是最基本的形式,适用于处理一维数组的区间求和问题。

2.1.1 算法实现

def build_prefix_sum(arr):"""构建一维前缀和数组Args:arr: 输入数组Returns:前缀和数组"""n = len(arr)prefix = [0] * nif n > 0:prefix[0] = arr[0]for i in range(1, n):prefix[i] = prefix[i-1] + arr[i]return prefixdef query_range_sum(prefix, l, r):"""查询区间和 [l, r]Args:prefix: 前缀和数组l: 区间左端点(包含)r: 区间右端点(包含)Returns:区间和"""if l == 0:return prefix[r]else:return prefix[r] - prefix[l-1]

2.1.2 示例与应用

考虑数组 [1, 2, 3, 4, 5],其前缀和数组为 [1, 3, 6, 10, 15]。

· 查询 [1, 3] 的和:prefix[3] - prefix[0] = 10 - 1 = 9 (2+3+4)
· 查询 [0, 2] 的和:prefix[2] = 6 (1+2+3)
· 查询 [2, 4] 的和:prefix[4] - prefix[1] = 15 - 3 = 12 (3+4+5)

2.2 二维前缀和

二维前缀和扩展了一维前缀和的概念,用于处理二维数组(矩阵)的子矩阵求和问题。

2.2.1 算法原理

对于二维数组 matrixmatrixmatrix,其前缀和数组 prefixprefixprefix 定义为:

prefix[i][j] = \sum_{x=0}^{i} \sum_{y=0}^{j} matrix[x][y]

子矩阵 (x1,y1)(x1, y1)(x1,y1)(x2,y2)(x2, y2)(x2,y2) 的和可以通过前缀和数组计算:

sum = prefix[x2][y2] - prefix[x1-1][y2] - prefix[x2][y1-1] + prefix[x1-1][y1-1]

2.2.2 算法实现

def build_2d_prefix_sum(matrix):"""构建二维前缀和数组Args:matrix: 二维输入数组Returns:二维前缀和数组"""if not matrix or not matrix[0]:return [[]]rows, cols = len(matrix), len(matrix[0])prefix = [[0] * cols for _ in range(rows)]# 初始化第一个元素prefix[0][0] = matrix[0][0]# 初始化第一行for j in range(1, cols):prefix[0][j] = prefix[0][j-1] + matrix[0][j]# 初始化第一列for i in range(1, rows):prefix[i][0] = prefix[i-1][0] + matrix[i][0]# 计算其余元素for i in range(1, rows):for j in range(1, cols):prefix[i][j] = (prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1] + matrix[i][j])return prefixdef query_submatrix_sum(prefix, x1, y1, x2, y2):"""查询子矩阵和Args:prefix: 二维前缀和数组x1, y1: 子矩阵左上角坐标x2, y2: 子矩阵右下角坐标Returns:子矩阵的和"""total = prefix[x2][y2]left = prefix[x2][y1-1] if y1 > 0 else 0top = prefix[x1-1][y2] if x1 > 0 else 0top_left = prefix[x1-1][y1-1] if (x1 > 0 and y1 > 0) else 0return total - left - top + top_left

2.2.3 示例与应用

考虑矩阵:

[[1, 2, 3],[4, 5, 6],[7, 8, 9]
]

其前缀和矩阵为:

[[1,  3,  6],[5,  12, 21],[12, 27, 45]
]

查询子矩阵 (1,1) 到 (2,2) 的和:

· prefix[2][2] = 45
· prefix[2][0] = 12 (y1-1=0)
· prefix[0][2] = 6 (x1-1=0)
· prefix[0][0] = 1
· 结果:45 - 12 - 6 + 1 = 28 (5+6+8+9)

第三章:前缀和的高级应用

3.1 差分数组技术

差分数组是前缀和的逆操作,常用于高效处理区间更新操作。

3.1.1 差分数组原理

给定数组 arrarrarr,其差分数组 diffdiffdiff 定义为: diff[i] = \begin{cases}
arr[0] & \text{if } i = 0 \
arr[i] - arr[i-1] & \text{if } i > 0
\end{cases}

对原数组区间 [l,r][l, r][l,r] 增加 kkk,只需更新差分数组: diff[l] += k

diff[r+1] -= k \quad (\text{if } r+1 < n)

然后通过前缀和操作可以从差分数组恢复原数组。

3.1.2 算法实现

class DifferenceArray:"""差分数组类"""def __init__(self, arr):"""初始化差分数组Args:arr: 输入数组"""self.n = len(arr)self.diff = [0] * self.nif self.n > 0:self.diff[0] = arr[0]for i in range(1, self.n):self.diff[i] = arr[i] - arr[i-1]def range_update(self, l, r, k):"""区间更新操作Args:l: 区间左端点r: 区间右端点k: 增加的值"""self.diff[l] += kif r + 1 < self.n:self.diff[r+1] -= kdef get_original(self):"""通过前缀和操作获取更新后的数组Returns:更新后的原数组"""result = [0] * self.nif self.n > 0:result[0] = self.diff[0]for i in range(1, self.n):result[i] = result[i-1] + self.diff[i]return result

3.2 滑动窗口问题

前缀和可以高效解决滑动窗口相关问题,特别是固定窗口大小的子数组求和问题。

3.2.1 固定大小滑动窗口

def max_sum_sliding_window(arr, k):"""寻找大小为k的滑动窗口的最大和Args:arr: 输入数组k: 窗口大小Returns:最大窗口和"""n = len(arr)if n == 0 or k <= 0 or k > n:return 0# 构建前缀和数组prefix = build_prefix_sum(arr)max_sum = float('-inf')# 计算每个窗口的和for i in range(k-1, n):window_sum = prefix[i] - (prefix[i-k] if i-k >= 0 else 0)max_sum = max(max_sum, window_sum)return max_sum

3.3 统计问题

前缀和可以用于高效解决各种统计问题,如计算平均值、方差等。

3.3.1 区间平均值计算

def range_average(prefix, count_prefix, l, r):"""计算区间平均值Args:prefix: 前缀和数组count_prefix: 元素计数前缀数组(用于处理可能为零的情况)l: 区间左端点r: 区间右端点Returns:区间平均值"""if l > r:return 0total = query_range_sum(prefix, l, r)count = count_prefix[r] - (count_prefix[l-1] if l > 0 else 0)return total / count if count > 0 else 0

第四章:前缀和的优化与变种

4.1 空间优化

在某些情况下,我们可以优化前缀和的空间使用,特别是当不需要存储整个前缀和数组时。

4.1.1 原地前缀和

def build_prefix_sum_inplace(arr):"""原地构建前缀和数组Args:arr: 输入数组,将被修改为前缀和数组"""for i in range(1, len(arr)):arr[i] += arr[i-1]

4.1.2 滚动前缀和

当只需要最近的前缀和值时,可以使用滚动变量而不是整个数组。

class RollingPrefix:"""滚动前缀和类"""def __init__(self):self.current_sum = 0self.prefix_history = []  # 可选:存储历史前缀和def add_value(self, value):"""添加新值到前缀和"""self.current_sum += valueself.prefix_history.append(self.current_sum)  # 可选:记录历史def get_current_sum(self):"""获取当前前缀和"""return self.current_sumdef reset(self):"""重置前缀和"""self.current_sum = 0self.prefix_history = []

4.2 多维前缀和优化

对于高维前缀和,我们可以使用更高效的构建和查询方法。

4.2.1 三维前缀和

def build_3d_prefix_sum(cube):"""构建三维前缀和数组Args:cube: 三维输入数组Returns:三维前缀和数组"""if not cube or not cube[0] or not cube[0][0]:return [[[]]]depth, rows, cols = len(cube), len(cube[0]), len(cube[0][0])prefix = [[[0] * cols for _ in range(rows)] for _ in range(depth)]# 初始化第一个元素prefix[0][0][0] = cube[0][0][0]# 初始化三个面,然后计算内部# 这里省略详细实现,原理与二维类似但更复杂return prefix

4.3 树状数组(Fenwick Tree)

树状数组是前缀和的一种高效实现变种,支持点更新和区间查询。

4.3.1 树状数组原理

树状数组利用二进制索引技术,可以在 O(log⁡n)O(\log n)O(logn) 时间内完成单点更新和前缀查询。

原数组: 1, 2, 3, 4, 5, 6, 7, 8
树状数组
节点1: 1
元素1
节点2: 3
元素2
节点3: 3
元素3
节点4: 10
元素4
节点5: 5
元素5
节点6: 11
元素6
节点7: 7
元素7
节点8: 36
元素8

4.3.2 树状数组实现

class FenwickTree:"""树状数组实现"""def __init__(self, arr):"""初始化树状数组Args:arr: 输入数组"""self.n = len(arr)self.tree = [0] * (self.n + 1)self.construct(arr)def construct(self, arr):"""构建树状数组"""for i in range(self.n):self.update(i, arr[i])def update(self, index, delta):"""更新操作Args:index: 索引位置delta: 变化值"""i = index + 1  # 树状数组索引从1开始while i <= self.n:self.tree[i] += deltai += i & -i  # 最低位1操作def query(self, index):"""查询前缀和 [0, index]Args:index: 索引位置Returns:前缀和"""total = 0i = index + 1  # 树状数组索引从1开始while i > 0:total += self.tree[i]i -= i & -i  # 最低位1操作return totaldef range_query(self, l, r):"""区间查询 [l, r]Args:l: 左端点r: 右端点Returns:区间和"""return self.query(r) - self.query(l-1)

第五章:完整代码实现与实战应用

下面是一个完整的前缀和应用示例,展示了如何解决多个实际问题。

# prefix_sum_applications.py
import numpy as np
from typing import List, Tupleclass PrefixSumApplications:"""前缀和应用类"""@staticmethoddef build_prefix_sum(arr: List[int]) -> List[int]:"""构建一维前缀和数组Args:arr: 输入数组Returns:前缀和数组"""n = len(arr)prefix = [0] * nif n > 0:prefix[0] = arr[0]for i in range(1, n):prefix[i] = prefix[i-1] + arr[i]return prefix@staticmethoddef build_2d_prefix_sum(matrix: List[List[int]]) -> List[List[int]]:"""构建二维前缀和数组Args:matrix: 二维输入数组Returns:二维前缀和数组"""if not matrix or not matrix[0]:return [[]]rows, cols = len(matrix), len(matrix[0])prefix = [[0] * cols for _ in range(rows)]# 初始化第一个元素prefix[0][0] = matrix[0][0]# 初始化第一行for j in range(1, cols):prefix[0][j] = prefix[0][j-1] + matrix[0][j]# 初始化第一列for i in range(1, rows):prefix[i][0] = prefix[i-1][0] + matrix[i][0]# 计算其余元素for i in range(1, rows):for j in range(1, cols):prefix[i][j] = (prefix[i-1][j] + prefix[i][j-1] - prefix[i-1][j-1] + matrix[i][j])return prefix@staticmethoddef query_range_sum(prefix: List[int], l: int, r: int) -> int:"""查询一维区间和Args:prefix: 前缀和数组l: 左端点r: 右端点Returns:区间和"""if l < 0 or r >= len(prefix) or l > r:return 0return prefix[r] - (prefix[l-1] if l > 0 else 0)@staticmethoddef query_submatrix_sum(prefix: List[List[int]], x1: int, y1: int, x2: int, y2: int) -> int:"""查询二维子矩阵和Args:prefix: 二维前缀和数组x1, y1: 左上角坐标x2, y2: 右下角坐标Returns:子矩阵和"""if not prefix or not prefix[0]:return 0rows, cols = len(prefix), len(prefix[0])if (x1 < 0 or x2 >= rows or y1 < 0 or y2 >= cols or x1 > x2 or y1 > y2):return 0total = prefix[x2][y2]left = prefix[x2][y1-1] if y1 > 0 else 0top = prefix[x1-1][y2] if x1 > 0 else 0top_left = prefix[x1-1][y1-1] if (x1 > 0 and y1 > 0) else 0return total - left - top + top_left@staticmethoddef max_subarray_sum(arr: List[int]) -> Tuple[int, int, int]:"""寻找最大子数组和(Kadane算法变种)Args:arr: 输入数组Returns:(最大和, 起始索引, 结束索引)"""n = len(arr)if n == 0:return 0, -1, -1prefix = PrefixSumApplications.build_prefix_sum(arr)min_prefix = 0min_index = -1max_sum = arr[0]start_idx = 0end_idx = 0for i in range(n):# 当前前缀和减去最小前缀和得到当前最大子数组和current_sum = prefix[i] - min_prefixif current_sum > max_sum:max_sum = current_sumstart_idx = min_index + 1end_idx = i# 更新最小前缀和if prefix[i] < min_prefix:min_prefix = prefix[i]min_index = ireturn max_sum, start_idx, end_idx@staticmethoddef count_zero_sum_subarrays(arr: List[int]) -> int:"""统计和为零的子数组数量Args:arr: 输入数组Returns:和为零的子数组数量"""from collections import defaultdictprefix = PrefixSumApplications.build_prefix_sum(arr)prefix_map = defaultdict(int)prefix_map[0] = 1  # 前缀和为0出现一次(空子数组)count = 0for sum_val in prefix:# 如果当前前缀和之前出现过,说明中间存在和为零的子数组count += prefix_map[sum_val]prefix_map[sum_val] += 1return count@staticmethoddef range_sum_queries(arr: List[int], queries: List[Tuple[int, int]]) -> List[int]:"""处理多个区间和查询Args:arr: 输入数组queries: 查询列表,每个查询是(l, r)元组Returns:每个查询的结果列表"""prefix = PrefixSumApplications.build_prefix_sum(arr)results = []for l, r in queries:results.append(PrefixSumApplications.query_range_sum(prefix, l, r))return results@staticmethoddef matrix_range_queries(matrix: List[List[int]], queries: List[Tuple[int, int, int, int]]) -> List[int]:"""处理多个子矩阵查询Args:matrix: 输入矩阵queries: 查询列表,每个查询是(x1, y1, x2, y2)元组Returns:每个查询的结果列表"""prefix = PrefixSumApplications.build_2d_prefix_sum(matrix)results = []for x1, y1, x2, y2 in queries:results.append(PrefixSumApplications.query_submatrix_sum(prefix, x1, y1, x2, y2))return results# 示例和使用代码
def main():# 创建应用实例app = PrefixSumApplications()# 示例1: 一维前缀和基本使用print("=== 一维前缀和示例 ===")arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]prefix = app.build_prefix_sum(arr)print(f"原数组: {arr}")print(f"前缀和: {prefix}")print(f"区间 [2, 5] 的和: {app.query_range_sum(prefix, 2, 5)}")  # 3+4+5+6=18# 示例2: 最大子数组和print("\n=== 最大子数组和示例 ===")arr2 = [-2, 1, -3, 4, -1, 2, 1, -5, 4]max_sum, start, end = app.max_subarray_sum(arr2)print(f"数组: {arr2}")print(f"最大子数组和: {max_sum}")  # 6print(f"子数组: {arr2[start:end+1]}")  # [4, -1, 2, 1]# 示例3: 统计和为零的子数组print("\n=== 和为零的子数组统计 ===")arr3 = [0, 0, 5, 5, -10, 10]zero_count = app.count_zero_sum_subarrays(arr3)print(f"数组: {arr3}")print(f"和为零的子数组数量: {zero_count}")  # 6# 示例4: 二维前缀和print("\n=== 二维前缀和示例 ===")matrix = [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12],[13, 14, 15, 16]]prefix_2d = app.build_2d_prefix_sum(matrix)print("原矩阵:")for row in matrix:print(row)print("\n前缀和矩阵:")for row in prefix_2d:print(row)# 查询子矩阵和submatrix_sum = app.query_submatrix_sum(prefix_2d, 1, 1, 2, 2)print(f"\n子矩阵 [1,1] 到 [2,2] 的和: {submatrix_sum}")  # 6+7+10+11=34# 示例5: 处理多个查询print("\n=== 多查询处理示例 ===")queries = [(0, 2), (1, 4), (3, 7), (0, 9)]results = app.range_sum_queries(arr, queries)print(f"数组: {arr}")for i, (l, r) in enumerate(queries):print(f"查询 [{l}, {r}]: {results[i]}")# 示例6: 矩阵多查询处理print("\n=== 矩阵多查询处理示例 ===")matrix_queries = [(0, 0, 1, 1), (1, 1, 2, 2), (0, 0, 3, 3)]matrix_results = app.matrix_range_queries(matrix, matrix_queries)for i, (x1, y1, x2, y2) in enumerate(matrix_queries):print(f"查询 [{x1},{y1}] 到 [{x2},{y2}]: {matrix_results[i]}")if __name__ == "__main__":main()

代码说明与自查

  1. 模块化设计:代码采用面向对象设计,将相关功能组织在类中
  2. 类型注解:使用了类型注解提高代码可读性和可维护性
  3. 错误处理:对可能的边界情况进行了处理
  4. 算法实现:实现了多种前缀和相关算法
  5. 示例丰富:提供了多个使用示例展示不同功能

自查清单:

· 所有函数都有适当的参数验证和错误处理
· 代码符合PEP 8规范,有清晰的注释和文档字符串
· 算法实现正确,包括边界情况处理
· 示例代码覆盖了主要功能和使用场景
· 使用了合适的算法和数据结构
· 变量命名清晰,代码可读性强

第六章:前缀和算法的时间空间分析

6.1 时间复杂度分析

前缀和算法的时间复杂度主要分为两个部分:

  1. 预处理阶段:
    · 一维前缀和:O(n)O(n)O(n)
    · 二维前缀和:O(m×n)O(m \times n)O(m×n),其中 mmmnnn 是矩阵的行数和列数
    · 三维前缀和:O(l×m×n)O(l \times m \times n)O(l×m×n)
  2. 查询阶段:
    · 一维区间查询:O(1)O(1)O(1)
    · 二维子矩阵查询:O(1)O(1)O(1)
    · 三维子立方体查询:O(1)O(1)O(1)

6.2 空间复杂度分析

前缀和算法的空间复杂度:

· 一维前缀和:O(n)O(n)O(n)
· 二维前缀和:O(m×n)O(m \times n)O(m×n)
· 三维前缀和:O(l×m×n)O(l \times m \times n)O(l×m×n)

6.3 适用场景分析

前缀和算法在以下场景中特别有效:

  1. 多次区间查询:当需要多次查询不同区间的和时
  2. 静态数据:数据不经常变化或变化后可以重新预处理
  3. 维度适中:对于高维数据,需要权衡空间开销和查询效率

第七章:前缀和的实际应用案例

7.1 图像处理中的积分图

在图像处理中,前缀和的概念被扩展为积分图(Integral Image),用于快速计算图像中任意矩形区域的像素和。

class IntegralImage:"""积分图类,用于图像处理"""def __init__(self, image):"""初始化积分图Args:image: 输入图像(二维数组)"""self.height = len(image)self.width = len(image[0]) if self.height > 0 else 0self.integral = self._compute_integral(image)def _compute_integral(self, image):"""计算积分图"""integral = [[0] * self.width for _ in range(self.height)]for i in range(self.height):for j in range(self.width):top = integral[i-1][j] if i > 0 else 0left = integral[i][j-1] if j > 0 else 0top_left = integral[i-1][j-1] if (i > 0 and j > 0) else 0integral[i][j] = image[i][j] + top + left - top_leftreturn integraldef region_sum(self, x1, y1, x2, y2):"""计算图像区域和Args:x1, y1: 区域左上角坐标x2, y2: 区域右下角坐标Returns:区域像素和"""total = self.integral[x2][y2]left = self.integral[x2][y1-1] if y1 > 0 else 0top = self.integral[x1-1][y2] if x1 > 0 else 0top_left = self.integral[x1-1][y1-1] if (x1 > 0 and y1 > 0) else 0return total - left - top + top_left

7.2 数据流分析

在数据流分析中,前缀和可以用于实时统计和分析数据流。

class DataStreamAnalyzer:"""数据流分析器,使用前缀和进行实时统计"""def __init__(self, window_size):"""初始化数据流分析器Args:window_size: 滑动窗口大小"""self.window_size = window_sizeself.data = []self.prefix = []self.current_sum = 0def add_data(self, value):"""添加新数据Args:value: 新数据值"""self.data.append(value)self.current_sum += valueself.prefix.append(self.current_sum)# 保持窗口大小if len(self.data) > self.window_size:old_value = self.data.pop(0)self.prefix.pop(0)self.current_sum -= old_value# 调整前缀和数组for i in range(len(self.prefix)):self.prefix[i] -= old_valuedef get_window_average(self):"""获取当前窗口平均值Returns:窗口平均值"""if not self.data:return 0return self.current_sum / len(self.data)def get_range_average(self, start, end):"""获取指定范围的平均值Args:start: 起始位置end: 结束位置Returns:范围平均值"""if not self.prefix or start < 0 or end >= len(self.prefix) or start > end:return 0total = self.prefix[end] - (self.prefix[start-1] if start > 0 else 0)return total / (end - start + 1)

结论

前缀和算法是一种简单而强大的技术,通过预处理数据来优化查询效率。本文全面介绍了前缀和的基本概念、实现方法、高级应用和实际案例。

通过本文的学习,您应该掌握:

  1. 一维和二维前缀和的构建和查询方法
  2. 前缀和在各种问题中的应用,如滑动窗口、区间查询、统计分析等
  3. 前缀和的优化技术和变种算法,如树状数组
  4. 前缀和在实际场景中的应用,如图像处理和数据流分析

前缀和算法的核心价值在于其能够将多次查询的时间复杂度从 O(n)O(n)O(n) 降低到 O(1)O(1)O(1),这种预处理-查询的模式在算法设计中具有广泛的应用。掌握前缀和算法不仅有助于解决具体的求和问题,更能培养一种重要的算法设计思维——通过合理的预处理来优化后续操作。

希望本文为您提供了深入且实用的前缀和算法指南。无论您是解决算法问题还是开发实际应用,前缀和都是一种值得掌握的重要技术。

http://www.dtcms.com/a/358323.html

相关文章:

  • 医疗AI时代的生物医学Go编程:高性能计算与精准医疗的案例分析(六)
  • react组件
  • C++优先级队列priority_queue的模拟实现
  • Trailing Zeros (计算 1 ~ n 中质因子 p 的数量)
  • Java全栈开发面试实战:从基础到高并发的全面解析
  • Redis数据类型概览:除了五大基础类型还有哪些?
  • leetcode643. 子数组最大平均数 I
  • AI-调查研究-65-机器人 机械臂控制技术的前世今生:从PLC到MPC
  • vscode+cmake+mingw64+opencv环境配置
  • wpf之依赖属性
  • 具有类人先验知识的 Affordance-觉察机器人灵巧抓取
  • C++_多态和虚构
  • 卡片一放,服务直达!实现信息零层级触达
  • Python实现京东商品数据自动化采集的实用指南
  • (双指针)Leetcode283.移动零-替换数字类别+Leetcode15. 三数之和
  • UI前端大数据可视化实战策略:如何设计符合用户认知的数据可视化界面?
  • 【计算机网络】HTTP是什么?
  • Ansible Playbook 调试与预演指南:从语法检查到连通性排查
  • 一体化步进伺服电机在汽车线束焊接设备中的应用案例
  • MongoDB 源码编译与调试:深入理解存储引擎设计 内容详细
  • HarmonyOS元服务开发
  • 深入解析HarmonyOS:UIAbility与Page的生命周期协同
  • TensorFlow 面试题及详细答案 120道(71-80)-- 性能优化与调试
  • 坚鹏请教DEEPSEEK:请问中国领先的AI智能体服务商有哪些?知行学
  • 深度学习系列 | Seq2Seq端到端翻译模型
  • 离线大文件与断点续传:ABP + TUS + MinIO/S3
  • IAR工程如何搭建vscode+clangd编辑环境
  • 如何使用快照将 AWS OpenSearch 服务中的数据从开发环境复制到生产环境
  • 互联网医院系统优势介绍
  • 嵌入式linux相机(2)