霍夫曼樹教程(個人總結版)

背景

霍夫曼樹(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.pswp.cn/bicheng/21001.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/21001.shtml
英文地址,請注明出處:http://en.pswp.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,發現…