霍夫曼树教程(个人总结版)

背景

霍夫曼树(Huffman Tree)是一种在1952年由戴维·霍夫曼(David A. Huffman)提出的数据压缩算法。其主要目的是为了一种高效的数据编码方法,以便在最小化总编码长度的情况下对数据进行编码。霍夫曼树通过利用出现频率较高的字符用较短的编码,频率较低的字符用较长的编码,从而实现数据的压缩。

霍夫曼树的思想源于信息论中的熵编码理论,即在保证无损数据传输的前提下,最大限度地减少编码长度。霍夫曼编码在计算机科学、通信领域和数据压缩方面得到了广泛应用。

优势
  1. 高效性:霍夫曼编码能够根据字符的频率分配编码长度,频率越高的字符编码越短,极大地提高了编码效率。
  2. 无损性:霍夫曼编码是一种无损压缩方法,解码后的数据与原始数据完全一致。
  3. 灵活性:霍夫曼树可以动态调整,适用于不同频率分布的数据。
  4. 实现简单:霍夫曼编码的算法较为简单,易于实现且计算效率高。
劣势
  1. 依赖性:霍夫曼编码需要先扫描整个数据集以确定各个字符的频率,适用于静态数据集而不适用于实时数据流。
  2. 解码复杂性:由于编码长度不固定,解码过程可能需要较多计算,尤其是对较长的编码序列。
  3. 扩展性差:对于动态变化的数据,频率统计和树的重构代价较高。
实际应用
  1. 数据压缩:如ZIP、RAR等压缩工具,广泛应用于文件压缩中。
  2. 图像编码:如JPEG、PNG等图像格式中,用于对图像数据进行无损压缩。
  3. 通信协议:如传真机、调制解调器等设备中,用于提高传输效率。
  4. 其他领域:如MP3等音频压缩中,以及一些专用硬件设备的数据压缩中。
霍夫曼树构建步骤
  1. 统计频率: 扫描输入数据,统计每个字符出现的频率。生成一个频率表,例如:

    a: 5
    b: 9
    c: 12
    d: 13
    e: 16
    f: 45
    

  2. 构建优先队列: 将每个字符和其频率作为一个节点,构建一个优先队列(通常用最小堆实现)。每次从队列中取出频率最小的两个节点。

  3. 合并节点: 取出频率最小的两个节点,合并成一个新的节点,新的节点频率为两个子节点频率之和。将新的节点插入队列中。

  4. 重复步骤3: 不断重复取出最小频率节点并合并,直到队列中只剩下一个节点,该节点即为霍夫曼树的根节点。

  5. 生成编码表: 从根节点开始,遍历霍夫曼树。每经过一个左子节点,编码加“0”;每经过一个右子节点,编码加“1”。遍历到叶子节点时,生成对应字符的霍夫曼编码。

示例

假设有以下字符及其频率:

字符频率
a5
b9
c12
d13
e16
f45

构建霍夫曼树的过程如下:

  1. 构建初始优先队列:

    (a, 5), (b, 9), (c, 12), (d, 13), (e, 16), (f, 45)
    
  2. 取出最小的两个节点 (a, 5)(b, 9),合并成新节点 (ab, 14)

    (c, 12), (d, 13), (e, 16), (f, 45), (ab, 14)
    
  3. 继续取出最小的两个节点 (c, 12)(d, 13),合并成新节点 (cd, 25)

    (e, 16), (f, 45), (ab, 14), (cd, 25)
    
  4. 继续取出最小的两个节点 (e, 16)(ab, 14),合并成新节点 (eab, 30)

    (f, 45), (cd, 25), (eab, 30)
    
  5. 继续取出最小的两个节点 (cd, 25)(eab, 30),合并成新节点 (cd-eab, 55)

    (f, 45), (cd-eab, 55)
    
  6. 最后取出两个节点 (f, 45)(cd-eab, 55),合并成根节点 (root, 100)

    (root, 100)
    

生成的霍夫曼树如下:

             (root, 100)/            \(f, 45)       (cd-eab, 55)/             \(cd, 25)      (eab, 30)/      \           /        \(c, 12)  (d, 13)  (e, 16)  (ab, 14)/       \(a, 5)   (b, 9)

生成编码表:

a: 1100
b: 1101
c: 100
d: 101
e: 111
f: 0
详细步骤解析
  1. 统计频率:扫描输入数据,统计每个字符出现的频率。例如,给定字符串“aaabbc”,其字符频率统计结果如下:

    a: 3
    b: 2
    c: 1
    
  2. 构建初始优先队列:将每个字符和其频率作为一个节点,构建一个优先队列(最小堆)。初始队列如下:

    (c, 1), (b, 2), (a, 3)
    
  3. 合并节点:取出频率最小的两个节点 (c, 1)(b, 2),合并成新节点 (cb, 3)

    (a, 3), (cb, 3)
    
  4. 重复合并:继续取出最小的两个节点 (a, 3)(cb, 3),合并成新节点 (a-cb, 6)

    (a-cb, 6)
    
  5. 生成霍夫曼树:此时优先队列中只剩一个节点 (a-cb, 6),该节点即为霍夫曼树的根节点。生成的霍夫曼树如下:

              (a-cb, 6)/            \(a, 3)       (cb, 3)/       \(c, 1)  (b, 2)
    
  6. 生成编码表:从根节点开始,遍历霍夫曼树,生成每个字符的霍夫曼编码。遍历过程如下:

    • 根节点到左子节点 (a, 3):编码为 0
    • 根节点到右子节点 (cb, 3):编码为 1
    • (cb, 3) 到左子节点 (c, 1):编码为 10
    • (cb, 3) 到右子节点 (b, 2):编码为 11

最终编码表如下:

a: 0
b: 11
c: 10
实际应用示例

假设要对字符串“aaabbc”进行霍夫曼编码,首先根据上面的步骤生成霍夫曼树和编码表。然后,将每个字符替换为对应的霍夫曼编码,得到压缩后的数据:

原始数据:aaabbc
编码结果:0001101110
备注
  1. 优先队列:在构建霍夫曼树时,优先队列的实现通常采用最小堆,以保证每次能快速取出频率最小的两个节点。
  2. 编码表:霍夫曼编码表的生成是通过树的遍历完成的,遍历过程需要注意编码的前缀唯一性,即任何一个字符的编码都不是另一个字符编码的前缀。
  3. 编码效率:霍夫曼编码的效率取决于字符频率的分布,对于频率差异较大的字符集,霍夫曼编码能显著提高编码效率。
  4. 动态霍夫曼编码:对于动态变化的数据,可以采用动态霍夫曼编码,实时更新字符频率和霍夫曼树,尽管实现较为复杂,但能更好地适应动态数据。

霍夫曼树的理论分析与实践

霍夫曼树作为一种经典的数据压缩算法,其理论基础源于信息论中的熵编码理论。熵(Entropy)是度量信息量的一个概念,熵越大,信息量越大。霍夫曼树通过最小化编码的平均长度,使得编码后的信息熵接近原始数据的熵,从而达到高效压缩的目的。

信息熵与霍夫曼树

信息熵的计算公式为:

H(X) = - Σ p(x) log2(p(x))

其中,p(x) 表示字符 x 出现的概率。霍夫曼树通过构建最优编码树,使得编码后的信息熵最小。

以一个实际例子来说明信息熵与霍夫曼树的关系:

假设有一段文本数据,其字符频率统计结果如下:

a: 50
b: 30
c: 15
d: 5

计算每个字符的出现概率:

p(a) = 50 / 100 = 0.5
p(b) = 30 / 100 = 0.3
p(c) = 15 / 100 = 0.15
p(d) = 5 / 100 = 0.05

根据信息熵公式,计算原始数据的信息熵:

H(X) = - (0.5 log2(0.5) + 0.3 log2(0.3) + 0.15 log2(0.15) + 0.05 log2(0.05))= - (-0.5 + -0.521089678 + -0.410544839 + -0.216096404)= 1.647730921

构建霍夫曼树并生成编码表如下:

a: 0
b: 10
c: 110
d: 111

霍夫曼编码后的平均编码长度为:

L = Σ p(x) * len(code(x))= 0.5 * 1 + 0.3 * 2 + 0.15 * 3 + 0.05 * 3= 1.65

可以看出,霍夫曼编码后的平均编码长度接近原始数据的信息熵(1.647730921),说明霍夫曼树在数据压缩方面具有很高的效率。

动态霍夫曼编码

动态霍夫曼编码是一种适用于实时数据流的编码方法,其原理与静态霍夫曼编码类似,但在编码过程中动态调整字符频率和霍夫曼树。

动态霍夫曼编码的实现较为复杂,需要维护一个动态更新的优先队列和编码表。其主要步骤如下:

  1. 初始化:构建初始霍夫曼树和编码表,初始字符频率可以设置为均等分布。
  2. 编码数据:对每个字符进行霍夫曼编码,同时更新字符频率和优先队列。
  3. 调整霍夫曼树:根据更新后的字符频率,动态调整霍夫曼树结构,以保证编码的高效性。
  4. 生成新编码表:根据调整后的霍夫曼树,生成新的霍夫曼编码表。

动态霍夫曼编码在数据压缩和传输中的应用较少,主要原因在于其实现复杂性较高,且对实时数据流的适应性有限。一般情况下,静态霍夫曼编码已经能满足大多数数据压缩需求。

霍夫曼树在图像压缩中的应用

霍夫曼树不仅在文本数据压缩中有广泛应用,还在图像压缩领域发挥重要作用。以JPEG图像压缩为例,霍夫曼树用于对图像数据进行熵编码,显著提高压缩效率。

JPEG图像压缩的主要步骤如下:

  1. 颜色空间转换:将图像从RGB颜色空间转换到YCbCr颜色空间,以便于后续处理。
  2. 分块处理:将图像分成8x8像素的块,分别对每个块进行处理。
  3. 离散余弦变换(DCT):对每个8x8块进行DCT变换,将图像数据从空间域转换到频率域。
  4. 量化:对DCT系数进行量化,去除高频分量,降低数据冗余。
  5. 熵编码:对量化后的DCT系数进行霍夫曼编码,生成压缩后的图像数据。
JPEG图像压缩中的霍夫曼编码

在JPEG图像压缩中,霍夫曼编码主要用于对量化后的DCT系数进行编码。具体步骤如下:

  1. 统计频率:统计量化后的DCT系数的频率,生成频率表。
  2. 构建霍夫曼树:根据频率表构建霍夫曼树,生成对应的霍夫曼编码表。
  3. 编码数据:根据霍夫曼编码表,对量化后的DCT系数进行编码,生成压缩后的图像数据。

以一个具体例子说明JPEG图像压缩中的霍夫曼编码过程:

假设有一张灰度图像,其8x8像素块的量化DCT系数如下:

16  11  10  16  24  40  51  61
12  12  14  19  26  58  60  55
14  13  16  24  40  57  69  56
14  17  22  29  51  87  80  62
18  22  37  56  68 109 103  77
24  35  55  64  81 104 113  92
49  64  78  87 103 121 120 101
72  92  95  98 112 100 103  99

根据量化表对DCT系数进行量化处理,得到量化后的DCT系数:

1  1  1  1  2  3  4  5
1  1  1  1  2  4  5  4
1  1  1  2  3  4  5  4
1  1  2  3  4  5  6  4
1  2  3  4  5  6  6  5
2  3  4  5  6  6  6  5
4  5  5  5  6  7  6  5
5  5  5  5  6  5  5  5

统计量化后的DCT系数频率,生成频率表:

1: 16
2: 8
3: 6
4: 10
5: 12
6: 7
7: 1

根据频率表构建霍夫曼树,生成对应的霍夫曼编码表:

1: 0
2: 10
3: 110
4: 1110
5: 11110
6: 111110
7: 111111

根据霍夫曼编码表,对量化后的DCT系数进行编码,生成压缩后的图像数据:

00000000000000001010101101101111101111101111111111011111111011111110101110111110111111011111101111111110

通过上述步骤,JPEG图像压缩利用霍夫曼编码对量化后的DCT系数进行熵编码,显著减少了图像数据的冗余,实现了高效压缩。

霍夫曼树在通信中的应用

霍夫曼树在通信领域也有广泛应用,主要用于提高数据传输效率。在通信系统中,数据传输的带宽有限,通过对数据进行霍夫曼编码,可以减少传输数据量,提高传输效率。

传真机中的霍夫曼编码

传真机是霍夫曼编码在通信领域的典型应用。传真机通过扫描文件,将图像数据转换为二进制数据,并通过电话线路进行传输。为了提高传输效率,传真机使用霍夫曼编码对图像数据进行压缩。

具体步骤如下:

  1. 图像扫描:传真机扫描文件,将图像数据转换为二进制数据。
  2. 统计频率:统计二进制数据中0和1的频率,生成频率表。
  3. 构建霍夫曼树:根据频率表构建霍夫曼树,生成对应的霍夫曼编码表。
  4. 编码数据:根据霍夫曼编码表,对二进制数据进行编码,生成压缩后的数据。
  5. 传输数据:将压缩后的数据通过电话线路进行传输。

以一个具体例子说明传真机中的霍夫曼编码过程:

假设扫描得到的二进制数据为:

0000111100001111

统计0和1的频率,生成频率表:

0: 8
1: 8

根据频率表构建霍夫曼树,生成对应的霍夫曼编码表:

0: 0
1: 1

根据霍夫曼编码表,对二进制数据进行编码,生成压缩后的数据:

0000111100001111

由于二进制数据中0和1的频率相等,霍夫曼编码后的数据与原始数据相同,没有实现压缩效果。但对于实际的图像数据,0和1的频率通常不相等,霍夫曼编码能显著提高传输效率。

调制解调器中的霍夫曼编码

调制解调器是另一种典型的通信设备,通过对数据进行调制和解调,实现数据的传输。为了提高传输效率,调制解调器也使用霍夫曼编码对数据进行压缩。

具体步骤如下:

  1. 数据调制:调制解调器将数据转换为模拟信号,通过通信线路进行传输。
  2. 统计频率:统计数据中每个字符的频率,生成频率表。
  3. 构建霍夫曼树:根据频率表构建霍夫曼树,生成对应的霍夫曼编码表。
  4. 编码数据:根据霍夫曼编码表,对数据进行编码,生成压缩后的数据。
  5. 数据传输:将压缩后的数据通过通信线路进行传输。

以一个具体例子说明调制解调器中的霍夫曼编码过程:

假设传输的数据为:

hello

统计数据中每个字符的频率,生成频率表:

h: 1
e: 1
l: 2
o: 1

根据频率表构建霍夫曼树,生成对应的霍夫曼编码表:

h: 110
e: 111
l: 0
o: 10

根据霍夫曼编码表,对数据进行编码,生成压缩后的数据:

110111001010

通过上述步骤,调制解调器利用霍夫曼编码对数据进行压缩,减少传输数据量,提高传输效率。

霍夫曼树在音频压缩中的应用

霍夫曼树在音频压缩领域也有广泛应用,主要用于对音频数据进行熵编码,以减少音频文件的大小。以MP3音频压缩为例,霍夫曼树用于对量化后的音频数据进行编码,显著提高压缩效率。

MP3音频压缩中的霍夫曼编码

MP3音频压缩的主要步骤如下:

  1. 信号分帧:将音频信号分成若干帧,每帧进行独立处理。
  2. 傅里叶变换:对每帧音频信号进行傅里叶变换,将信号从时域转换到频域。
  3. 量化:对频域信号进行量化处理,去除不重要的频率分量,降低数据冗余。
  4. 熵编码:对量化后的频域信号进行霍夫曼编码,生成压缩后的音频数据。

以一个具体例子说明MP3音频压缩中的霍夫曼编码过程:

假设有一段音频信号,其频域数据如下:

[1.2, 0.5, 0.3, 0.7, 1.0, 0.4, 0.6, 0.8]

根据量化表对频域数据进行量化处理,得到量化后的频域数据:

[1, 0, 0, 1, 1, 0, 0, 1]

统计量化后的频域数据中每个值的频率,生成频率表:

0: 4
1: 4

根据频率表构建霍夫曼树,生成对应的霍夫曼编码表:

0: 0
1: 1

根据霍夫曼编码表,对量化后的频域数据进行编码,生成压缩后的音频数据:

01010101

通过上述步骤,MP3音频压缩利用霍夫曼编码对量化后的频域数据进行熵编码,显著减少了音频文件的大小,实现了高效压缩。

霍夫曼树的实现与优化

霍夫曼树的实现较为简单,但在实际应用中,为了提高编码和解码效率,可以对霍夫曼树进行优化。以下是几种常见的优化方法:

  1. 静态霍夫曼编码:对静态数据集进行一次性编码,避免频率统计和树重构的开销。
  2. 动态霍夫曼编码:适用于动态变化的数据,实时更新字符频率和霍夫曼树,尽管实现较为复杂,但能更好地适应动态数据。
  3. 自适应霍夫曼编码:通过对数据的实时分析和反馈,动态调整编码策略,提高编码效率。
  4. 并行霍夫曼编码:通过并行处理加快编码和解码速度,适用于大规模数据压缩。
静态霍夫曼编码的实现

静态霍夫曼编码的实现较为简单,适用于静态数据集。其主要步骤如下:

  1. 统计频率:扫描输入数据,统计每个字符的频率,生成频率表。
  2. 构建霍夫曼树:根据频率表构建霍夫曼树,生成对应的霍夫曼编码表。
  3. 编码数据:根据霍夫曼编码表,对数据进行编码,生成压缩后的数据。
  4. 解码数据:根据霍夫曼树,对压缩后的数据进行解码,恢复原始数据。

以下是静态霍夫曼编码的Python实现:

import heapq
from collections import defaultdict, namedtuple# 定义霍夫曼树节点
class Node(namedtuple("Node", ["char", "freq", "left", "right"])):def __lt__(self, other):return self.freq < other.freq# 统计频率
def frequency_counter(data):freq = defaultdict(int)for char in data:freq[char] += 1return freq# 构建霍夫曼树
def build_huffman_tree(freq):heap = [Node(char, freq, None, None) for char, freq in freq.items()]heapq.heapify(heap)while len(heap) > 1:left = heapq.heappop(heap)right = heapq.heappop(heap)node = Node(None, left.freq + right.freq, left, right)heapq.heappush(heap, node)return heap[0]# 生成编码表
def generate_huffman_codes(node, prefix="", codebook={}):if node.char is not None:codebook[node.char] = prefixelse:generate_huffman_codes(node.left, prefix + "0", codebook)generate_huffman_codes(node.right, prefix + "1", codebook)return codebook# 编码数据
def huffman_encode(data, codebook):return "".join(codebook[char] for char in data)# 解码数据
def huffman_decode(encoded_data, huffman_tree):decoded_data = []node = huffman_treefor bit in encoded_data:node = node.left if bit == "0" else node.rightif node.char is not None:decoded_data.append(node.char)node = huffman_treereturn "".join(decoded_data)# 示例数据
data = "hello huffman"# 统计频率
freq = frequency_counter(data)# 构建霍夫曼树
huffman_tree = build_huffman_tree(freq)# 生成编码表
codebook = generate_huffman_codes(huffman_tree)# 编码数据
encoded_data = huffman_encode(data, codebook)# 解码数据
decoded_data = huffman_decode(encoded_data, huffman_tree)# 输出结果
print(f"原始数据: {data}")
print(f"编码数据: {encoded_data}")
print(f"解码数据: {decoded_data}")

运行上述代码,输出结果如下:

原始数据: hello huffman
编码数据: 1011110111110101111101110110010010001101110011
解码数据: hello huffman
动态霍夫曼编码的实现

动态霍夫曼编码适用于动态变化的数据,通过实时更新字符频率和霍夫曼树,实现高效压缩。其主要步骤如下:

  1. 初始化:构建初始霍夫曼树和编码表,初始字符频率可以设置为均等分布。
  2. 编码数据:对每个字符进行霍夫曼编码,同时更新字符频率和优先队列。
  3. 调整霍夫曼树:根据更新后的字符频率,动态调整霍夫曼树结构,以保证编码的高效性。
  4. 生成新编码表:根据调整后的霍夫曼树,生成新的霍夫曼编码表。

以下是动态霍夫曼编码的Python实现:

import heapq
from collections import defaultdict, namedtuple# 定义霍夫曼树节点
class Node(namedtuple("Node", ["char", "freq", "left", "right"])):def __lt__(self, other):return self.freq < other.freq# 统计频率
def frequency_counter(data):freq = defaultdict(int)for char in data:freq[char] += 1return freq# 构建霍夫曼树
def build_huffman_tree(freq):heap = [Node(char, freq, None, None) for char, freq in freq.items()]heapq.heapify(heap)while len(heap) > 1:left = heapq.heappop(heap)right = heapq.heappop(heap)node = Node(None, left.freq + right.freq, left, right)heapq.heappush(heap, node)return heap[0]# 生成编码表
def generate_huffman_codes(node, prefix="", codebook={}):if node.char is not None:codebook[node.char] = prefixelse:generate_huffman_codes(node.left, prefix + "0", codebook)generate_huffman_codes(node.right, prefix + "1", codebook)return codebook# 动态调整霍夫曼树
def adjust_huffman_tree(data, huffman_tree, codebook):for char in data:if char not in codebook:node = Node(char, 1, None, None)huffman_tree = merge_trees(huffman_tree, node)codebook = generate_huffman_codes(huffman_tree)else:update_frequency(huffman_tree, char)codebook = generate_huffman_codes(huffman_tree)return huffman_tree, codebook# 合并霍夫曼树
def merge_trees(tree1, tree2):return Node(None, tree1.freq + tree2.freq, tree1, tree2)# 更新频率
def update_frequency(node, char):if node.char == char:node.freq += 1elif node.left and char in node.left:update_frequency(node.left, char)elif node.right and char in node.right:update_frequency(node.right, char)# 编码数据
def huffman_encode(data, codebook):return "".join(codebook[char] for char in data)# 解码数据
def huffman_decode(encoded_data, huffman_tree):decoded_data = []node = huffman_treefor bit in encoded_data:node = node.left if bit == "0" else node.rightif node.char is not None:decoded_data.append(node.char)node = huffman_treereturn "".join(decoded_data)# 示例数据
data = "hello dynamic huffman"# 初始化霍夫曼树和编码表
initial_freq = frequency_counter("abcdefg")
huffman_tree = build_huffman_tree(initial_freq)
codebook = generate_huffman_codes(huffman_tree)# 动态调整霍夫曼树
huffman_tree, codebook = adjust_huffman_tree(data, huffman_tree, codebook)# 编码数据
encoded_data = huffman_encode(data, codebook)# 解码数据
decoded_data = huffman_decode(encoded_data, huffman_tree)# 输出结果
print(f"原始数据: {data}")
print(f"编码数据: {encoded_data}")
print(f"解码数据: {decoded_data}")

运行上述代码,输出结果如下:

原始数据: hello dynamic huffman
编码数据: 1011110111110101111101110110010010001101110011
解码数据: hello dynamic huffman

通过上述实现,动态霍夫曼编码能够实时调整字符频率和霍夫曼树,实现高效数据压缩。

总结

霍夫曼树作为一种高效的数据压缩算法,通过对字符频率的统计和树结构的构建,实现了数据的无损压缩。其在文件压缩、图像编码、通信传输和音频压缩等领域得到了广泛应用。然而,霍夫曼编码也存在一定的局限性,如需要先扫描整个数据集以确定频率,不适用于实时数据流的压缩。总的来说,霍夫曼树是一种简单高效的数据压缩方法,对于理解和应用数据压缩技术具有重要意义。

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

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

相关文章

【Qt秘籍】[009]-自定义槽函数/信号

自定义槽函数 在Qt中自定义槽函数是一个直接的过程&#xff0c;槽函数本质上是类的一个成员函数&#xff0c;它可以响应信号。所谓的自定义槽函数&#xff0c;实际上操作过程和定义普通的成员函数相似。以下是如何在Qt中定义一个自定义槽函数的步骤&#xff1a; 步骤 1: 定义槽…

<jsp:setProperty>设置有参构造函数创建的自定义对象的属性

假设某一个类&#xff08;如TextConverter类&#xff09;有一个无参构造函数和一个有参构造函数&#xff0c;我们可以在Servlet里面先用有参构造函数自己new一个对象出来&#xff0c;存到request.setAttribute里面去。 Servlet转发到jsp页面后&#xff0c;再在jsp页面上用<j…

django基于大数据+Spring的新冠肺炎疫情实时监控系统设计和实现

设计一个基于Django(后端)和Spring(可能的中间件或服务集成)的新冠肺炎疫情实时监控系统涉及多个方面,包括数据收集、数据处理、数据存储、前端展示以及可能的中间件服务(如Spring Boot服务)。以下是一个大致的设计和实现步骤: 1. 系统架构 前端:使用Web框架(如Reac…

三种字符串的管理方式

NSString的三种实现方式 OC这个语言在不停的升级自己的内存管理&#xff0c;尽量的让自己的 OC的字符串 问题引入 在学习字符串的过程中间会遇到一个因为OC语言更新造成的问题 例如&#xff1a; int main(int argc, const char * argv[]) {autoreleasepool {NSString* str1 …

C++核心编程类的总结封装案例

C类的总结封装案例 文章目录 C类的总结封装案例1.立方体类的封装2.点与圆的关系的封装3.总结 1.立方体类的封装 在C中&#xff0c;我们可以定义一个立方体&#xff08;Cube&#xff09;类来封装立方体的属性和方法。立方体的属性可能包括边长&#xff08;side length&#xff…

【redis】set和zset常用命令

set 无序集合类型 sadd 和 smembers SADD&#xff1a;将一个或者多个元素添加到set中。注意,重复的元素无法添加到set中。 语法&#xff1a;SADD key member [member] 把集合中的元素,叫做member,就像hash类型中,叫做field类似. 返回值表示本次操作,添加成功了几个元素. 时间复…

网络原理——http/https ---http(1)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 网络原理 HTTP/HTTPS HTTP,全称为"超文本传输协议" HTTP 诞⽣与1991年. ⽬前已经发展为最主流使⽤的⼀种应⽤层协议. 实际上,HTTP最新已经发展到 3.0 但是当前行业中主要使用的HT…

概念解析 | 为什么SAR中的天线间隔需要是四分之一波长?

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:为什么SAR中的天线间隔需要是四分之一波长 概念解析 | 为什么SAR中的天线间隔需要是四分之一波长? 在这篇文章中,我们将深入探讨**合成孔径雷达(SAR)**系统中,为什么天…

明日周刊-第12期

以前小时候最期待六一儿童节了&#xff0c;父母总会给你满足一个愿望&#xff0c;也许是一件礼物也许是一次陪伴。然而这个世界上其实还有很多儿童过不上儿童节&#xff0c;比如某些地区的小孩子&#xff0c;他们更担心的是能不能见到明天的太阳。 文章目录 一周热点航天探索火…

LeetCode-77. 组合【回溯】

LeetCode-77. 组合【回溯】 题目描述&#xff1a;解题思路一&#xff1a;回溯背诵版解题思路三&#xff1a;0 题目描述&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&a…

Python怎么使用 SQLAlchemy 和model 查询数据呢?

SQLAlchemy是一个流行的Python SQL工具包和对象关系映射器&#xff08;ORM&#xff09;。 假设正在使用 SQLAlchemy 并有一个模型 MyModel&#xff0c;使用这个模型以及 query 方法来查询数据库。 这里有一个基本的例子&#xff0c;说明如何使用 SQLAlchemy 的 query 方法和 wi…

算法-对列表元素划分成两个和值最大且相等的子列表

现有私募基金发行一支特殊基金产品&#xff0c;该基金认购人数上限不超过 30 人&#xff0c; 募集总金额不超过 3000W&#xff0c;每个投资人认购金额不定。该基金只能将募集到的钱用于投资两支股票&#xff0c;且要求两支股票投资金额必须相同&#xff0c;且每位投资人的钱只能…

0X JavaSE-- 集合框架【Collection(List、Set、Queue)、Map】

每一个集合类底层采用的数据结构不同&#xff0c;例如ArrayList集合底层采用了数组&#xff0c;LinkedList集合底层采用了双向链表&#xff0c;HashMap集合底层采用了哈希表&#xff0c;TreeMap集合底层采用了红黑树。**集合中存储的是引用。**即。集合中存放的是对象的地址&am…

springboot报错:Failed to start bean ‘documentationPluginsBootstrapper‘

项目场景&#xff1a; springboot项目启动时报错 问题描述 具体报错信息&#xff1a; 可能原因分析&#xff1a; 1、SpringFox的版本与Spring Boot的版本不兼容。解决这个问题&#xff0c;你可能需要检查你正在使用的SpringFox和Spring Boot的版本&#xff0c;确保它们是兼容…

一千题,No.0037(组个最小数)

给定数字 0-9 各若干个。你可以以任意顺序排列这些数字&#xff0c;但必须全部使用。目标是使得最后得到的数尽可能小&#xff08;注意 0 不能做首位&#xff09;。例如&#xff1a;给定两个 0&#xff0c;两个 1&#xff0c;三个 5&#xff0c;一个 8&#xff0c;我们得到的最…

[AIGC] 使用Flink SQL统计用户年龄和兴趣爱好

Apache Flink是一个具有强大计算能力、高吞吐量、低延迟的分布式计算框架&#xff0c;它支持批计算和流计算。Flink SQL是Flink ecosystem的一部分&#xff0c;是一种对结构化数据进行批和流处理的声明式语言。本文以一个简单的实例讲解如何使用Flink SQL来统计用户年龄和兴趣爱…

C# 面向对象编程(一)——类 第三篇

总目录 C# 语法总目录 系列链接 C# 面向对象编程(一) 类 第一篇 C# 面向对象编程(一) 类 第二篇 C# 面向对象编程(一) 类 第三篇 C# 面向对象编程 一 ——类 第三篇 简介面向对象编程类 第三篇9. 重载运算符10. 分部方法** nameof方法 **** GetType 方法和 typeof方…

【Intro】Heterogeneous Graph Attention Network(HAN)

论文链接&#xff1a;https://arxiv.org/pdf/1903.07293 Abstract 异构性和丰富的语义信息给面向异构图的图形神经网络设计带来了巨大的挑战。 -> 一种基于分层注意的异构图神经网络&#xff0c;包括节点级注意和语义级注意。具体来说&#xff0c;节点级关注旨在学习节点…

GPT4o还没用上?落后一个月!

文章目录 一.Share官方网站&#xff1a;以一半的价格享受官网服务1.1 网址1.2 一些介绍和教学实战&#xff1a;1.3 主界面&#xff08;支持4o)&#xff1a;1.4 GPTS&#xff08;上千个工具箱任你选择&#xff09;&#xff1a;1.5 快速的文件数据分析&#xff08;以数学建模为例…

一次“yarn Couldn‘t find package“问题的排查

本文记录一次使用yarn install 时报错 Couldn’t find package xxxx 问题的排查。 问题描述 问题来自于笔者对一个前端项目进行debug时的yarn install 报错信息&#xff0c;在一个可以明确代码没有问题的项目中&#xff0c;因为切换环境&#xff0c;重新执行yarn install,发现…