算法基礎 -- 字符串哈希的基本概念和數學原理分析

字符串哈希的基本概念和數學原理分析

1. 字符串哈希的定義和基本概念

哈希函數的定義

哈希函數(Hash Function)是一種將任意長度的輸入映射為固定長度輸出的函數。對于字符串而言,哈希函數通過某種算法將字符串轉換成一個整數,該整數稱為哈希值。良好的哈希函數通常具有以下特性:

  • 確定性(Deterministic):相同的輸入必須產生相同的哈希值。
  • 均勻分布(Uniformity):不同輸入的哈希值應盡可能均勻分布,避免哈希沖突(不同輸入產生相同哈希值)。

字符串哈希的作用

將字符串轉換為哈希值,可以顯著提升字符串比較和查找的效率。例如,在字符串匹配算法 Rabin-Karp 中,哈希值可以用于快速篩選可能匹配的位置,從而減少逐字符比較的次數。

哈希沖突及其處理

由于哈希函數將龐大的輸入空間映射到有限的輸出空間,不可避免地會發生哈希沖突(Collision)。即,可能存在 Hash(S) = Hash(T),但 S ≠ T

解決哈希沖突的方法:

  • 數據結構層面(哈希表)
    • 開鏈法:使用鏈表存儲沖突元素。
    • 開放地址法:在哈希沖突時尋找下一個可用槽位(線性探測、二次探測、雙重哈希)。
  • 字符串算法層面
    • 雙哈希(Double Hashing):使用兩個不同的哈希函數,只有兩個哈希值都相等時才認為字符串相等。
    • 增大哈希空間:選取更大的模數 M M M 以減少沖突概率。
    • 最終驗證:在哈希值相等時進行字符串逐字符比對。

2. 字符串哈希的數學原理

多項式哈希(Polynomial Hashing)

字符串哈希常用的方法之一是多項式哈希,其基本思想是將字符串視為某個進制的數,并進行模運算。形式化定義如下:

H ( S ) = ( s 1 × B n ? 1 + s 2 × B n ? 2 + ? + s n × B 0 ) m o d M . H(S) = \big( s_1 \times B^{n-1} + s_2 \times B^{n-2} + \dots + s_n \times B^0 \big) \bmod M \,. H(S)=(s1?×Bn?1+s2?×Bn?2+?+sn?×B0)modM.

其中:

  • s i s_i si?:第 i i i 個字符的數值(如 ASCII 編碼)。
  • B B B:基數(通常選 31、131、13331 等)。
  • M M M:模數(通常選大質數,如 1 0 9 + 7 10^9+7 109+7)。

示例:
對于字符串 "abcde",假設 a=1, b=2, ..., e=5,且 B = 31 B=31 B=31,則:
H ( " a b c d e " ) = ( 1 × 3 1 4 + 2 × 3 1 3 + 3 × 3 1 2 + 4 × 3 1 1 + 5 × 3 1 0 ) m o d M . H("abcde") = (1 \times 31^4 + 2 \times 31^3 + 3 \times 31^2 + 4 \times 31^1 + 5 \times 31^0) \bmod M. H("abcde")=(1×314+2×313+3×312+4×311+5×310)modM.

基數 B B B 和模數 M M M 的選擇

  • 模數 M M M
    • 應選大質數,以減少哈希沖突,如 1 0 9 + 7 10^9+7 109+7
    • 也可選 2 64 2^{64} 264 直接利用整數溢出(非質數)。
  • 基數 B B B
    • 通常選取比字符集大小更大的質數,如 31、131、13331。
    • 選質數可減少哈希值模式性,提高均勻分布性。

滾動哈希(Rolling Hash)

滾動哈希是一種 O ( 1 ) O(1) O(1) 時間計算滑動窗口子串哈希的方法,推導如下:

H ( i ) H(i) H(i) 表示 S[i:i+m-1] 的哈希值:
H ( i ) = ( s i × B m ? 1 + s i + 1 × B m ? 2 + ? + s i + m ? 1 × B 0 ) m o d M . H(i) = (s_i \times B^{m-1} + s_{i+1} \times B^{m-2} + \dots + s_{i+m-1} \times B^0) \bmod M. H(i)=(si?×Bm?1+si+1?×Bm?2+?+si+m?1?×B0)modM.

計算 H ( i + 1 ) H(i+1) H(i+1) 時,可由 H ( i ) H(i) H(i) 推導:
H ( i + 1 ) = ( H ( i ) × B ? s i × B m + s i + m ) m o d M . H(i+1) = \Big( H(i) \times B - s_i \times B^m + s_{i+m} \Big) \bmod M. H(i+1)=(H(i)×B?si?×Bm+si+m?)modM.

該方法避免了重新計算每個子串的哈希值,大幅提升效率。


3. 字符串哈希的常見算法

Rabin-Karp 算法

Rabin-Karp 通過滑動窗口 + 哈希匹配實現高效字符串查找:

  1. 計算模式串 P P P 的哈希值 H ( P ) H(P) H(P)
  2. 在文本串中滑動窗口計算每個子串哈希值 H T ( i ) H_T(i) HT?(i)
  3. H T ( i ) = H ( P ) H_T(i) = H(P) HT?(i)=H(P),則進一步驗證字符串是否完全匹配。

時間復雜度分析

  • 樸素匹配算法: O ( n m ) O(nm) O(nm)
  • Rabin-Karp:
    • 預處理模式串: O ( m ) O(m) O(m)
    • 計算 n ? m + 1 n-m+1 n?m+1 個子串哈希: O ( n ) O(n) O(n)
    • 平均復雜度 O ( n + m ) O(n+m) O(n+m),最壞情況下(哈希沖突過多) O ( n m ) O(nm) O(nm)

4. 字符串哈希的時間與空間復雜度

操作樸素方法哈希方法
單次字符串比較 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)
查找子串 O ( n m ) O(nm) O(nm) O ( n + m ) O(n+m) O(n+m)(Rabin-Karp)
哈希計算 O ( n ) O(n) O(n) O ( n ) O(n) O(n)
滾動哈希更新 O ( n m ) O(nm) O(nm) O ( n ) O(n) O(n)
哈希表查找 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)(均攤)

5. 字符串哈希的應用場景

字符串匹配

  • 單模式匹配:Rabin-Karp 算法。
  • 多模式匹配:對多個模式串建立哈希表。

重復字符串檢測

  • 大數據集合查重:Bloom Filter 結合哈希可快速去重。
  • 文檔查重:對固定長度子串進行哈希比對。

哈希索引(數據存儲)

  • 哈希表(Hash Table):字符串鍵值存儲,如 Python dict
  • 數據庫索引:MySQL 等數據庫采用哈希索引加速查詢。

數據完整性校驗

  • 文件哈希(MD5、SHA-256):用于數據校驗、防止篡改。
  • Git 版本管理:Git 采用 SHA-1 哈希標識文件版本。

分布式系統

  • 一致性哈希:用于負載均衡,如緩存服務器的分片管理。
  • DHT(分布式哈希表):用于 P2P 網絡中的數據存儲。

總結

字符串哈希是一種強大且高效的字符串處理技術,廣泛應用于字符串匹配、查重、數據存儲和分布式計算等領域。合理選擇哈希函數的參數(如基數 B B B 和模數 M M M),并結合滾動哈希雙重哈希等技術,可以大幅提升字符串處理的性能,并降低哈希沖突帶來的影響。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896833.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896833.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896833.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從新加坡《Companion Guide on Securing AI Systems 》看可信AI全生命周期防護框架構建

從新加坡《AI系統安全指南配套手冊》看可信AI全生命周期防護框架構建 一、引言 1.1 研究背景與意義 近年來,人工智能(AI)技術以前所未有的速度蓬勃發展,已然成為推動各行業變革與創新的核心驅動力。從醫療領域輔助疾病診斷,到金融行業的風險預測與智能投顧,再到交通領…

C++學習之C++初識、C++對C語言增強、對C語言擴展

一.C初識 1.C簡介 2.第一個C程序 //#include <iostream> //iostream 相當于 C語言下的 stdio.h i - input 輸入 o -output 輸出 //using namespace std; //using 使用 namespace 命名空間 std 標準 &#xff0c;理解為打開一個房間&#xff0c;房間里有我們所需…

HTMLS基本結構及標簽

HTML5是目前制作網頁的核心技術&#xff0c;有叫超文本標記語言。 基本結構 聲明部分位于文檔的最前面&#xff0c;用于向瀏覽器說明當前文檔使用HTML標準規范。 根部標簽位于聲明部分后&#xff0c;用于告知瀏覽器這是一個HTML文檔。< html>表示文檔開始&#xff0c;&l…

eMMC存儲器詳解(存儲區域結構、EXT_CSD[179]、各分區介紹、主要引腳、命令格式與類型等)

讀本篇博文所需要的先行知識 關于芯片內部的ROM的作用、工作原理的介紹&#xff0c;鏈接如下&#xff1a; https://blog.csdn.net/wenhao_ir/article/details/145969584 eMMC的物理結構、特點、用途 這個標題的相關內容見我的另一篇博文&#xff0c;博文鏈接如下&#xff1a…

分布式鎖—2.Redisson的可重入鎖一

大綱 1.Redisson可重入鎖RedissonLock概述 2.可重入鎖源碼之創建RedissonClient實例 3.可重入鎖源碼之lua腳本加鎖邏輯 4.可重入鎖源碼之WatchDog維持加鎖邏輯 5.可重入鎖源碼之可重入加鎖邏輯 6.可重入鎖源碼之鎖的互斥阻塞邏輯 7.可重入鎖源碼之釋放鎖邏輯 8.可重入鎖…

iOS實現一個強大的本地狀態記錄容器

我們開發中經常會遇到這樣的場景&#xff0c;就是我們客戶端用戶進行了某個操作&#xff0c;這個操作影響了數據的狀態&#xff0c;但是我們又不方便重新請求一次數據&#xff0c; 這個時候&#xff0c;就需要我們記錄一下本地狀態在內存中&#xff0c;隨著業務越來越復雜&…

vue中帶$的是什么

在Vue.js中&#xff0c;帶的 $ 符號用于表示 Vue實例的屬性和方法。 這些屬性和方法是Vue框架內部定義的&#xff0c;主要用于方便開發者在組件內部訪問和使用。 常見的帶$的屬性和方法: ?$data?&#xff1a;用于訪問組件的內部數據對象&#xff0c;包含組件內定義的所有響…

杰和科技工業整機AF208|防塵+靜音+全天候運行

在特殊的工業環境中&#xff0c;實現快速生產離不開各類工業計算機的強大支持。杰和科技工業計算機AF208&#xff0c;作為核心控制單元&#xff0c;憑借其堅固可靠的外殼、先進的散熱技術以及緊湊靈活的部署特點&#xff0c;發揮著關鍵作用。 硬實力外殼&#xff0c;無懼塵埃 …

【django】模型部署過程

模型部署 示例&#xff1a;保存 Scikit-learn 模型myapp/views.py全局加載模型tasks.py&#xff08;Celery任務&#xff09;views.py 修改為異步調用views.py 準備工作 模型保存格式 確保你的模型已保存為可加載的格式&#xff1a; ● TensorFlow/Keras&#xff1a;.h5 或 Save…

一、計算機網絡技術——概述、性能指標

網絡技術發展歷程 第一階段 一九六九年美國國防部研制的ARPANET&#xff0c;采用“接口報文處理機”將四臺獨立的計算機主機互聯在一起&#xff0c;實現數據的轉發。 這一階段的主要特點是TCP/IP協議初步成型 第二階段&#xff1a; 采用三級結構&#xff0c;這一階段的主要…

【向量數據庫Weaviate】與ChromaDB的差異、優劣

以下是 Weaviate 和 ChromaDB 的詳細對比&#xff0c;涵蓋設計目標、核心功能、性能、適用場景及優劣勢分析&#xff1a; 1. 核心定位與設計目標 維度WeaviateChromaDB類型向量數據庫 圖數據庫&#xff08;支持混合搜索&#xff09;輕量級純向量數據庫&#xff08;專注嵌入存…

Lua | 每日一練 (4)

&#x1f4a2;歡迎來到張胤塵的技術站 &#x1f4a5;技術如江河&#xff0c;匯聚眾志成。代碼似星辰&#xff0c;照亮行征程。開源精神長&#xff0c;傳承永不忘。攜手共前行&#xff0c;未來更輝煌&#x1f4a5; 文章目錄 Lua | 每日一練 (4)題目參考答案線程和協程調度方式上…

Fiji —— 基于 imageJ 的免費且開源的圖像處理軟件

文章目錄 一、Fiji —— 用于科學圖像處理和分析1.1、工具安裝&#xff08;免費&#xff09;1.2、源碼下載&#xff08;免費&#xff09; 二、功能詳解2.0、Fiji - ImageJ&#xff08;Web應用程序&#xff09;2.1、常用功能&#xff08;匯總&#xff09;2.2、Fiji - Plugins&am…

PyQT(PySide)的上下文菜單策略設置setContextMenuPolicy()

在 Qt 中&#xff0c;QWidget 類提供了幾種不同的上下文菜單策略&#xff0c;這些策略通過 Qt::ContextMenuPolicy 枚舉類型來定義&#xff0c;用于控制控件&#xff08;如按鈕、文本框等&#xff09;在用戶右鍵點擊時如何顯示上下文菜單。 以下是 Qt::ContextMenuPolicy 枚舉中…

快慢指針【等分鏈表、判斷鏈表中是否存在環】

一、等分鏈表&#xff1a;找到鏈表的中間節點 Java 實現 class ListNode {int val;ListNode next;ListNode(int val) {this.val val;this.next null;} }public class MiddleOfLinkedList {public ListNode findMiddleNode(ListNode head) {if (head null) {return null;}L…

系統架構設計師—計算機基礎篇—計算機網絡

文章目錄 網絡互聯模型網絡協議與標準應用層協議FTP協議TFTP協議 HTTP協議HTTPS協議 DHCP動態主機配置協議DNS協議迭代查詢遞歸查詢 傳輸層協議網絡層協議IPV4協議IPV6協議IPV6數據報的目的地址IPV4到IPV6的過渡技術 網絡設計分層設計接入層匯聚層核心層 網絡布線綜合布線系統工…

計算機基礎面試(操作系統)

操作系統 1. 什么是進程和線程&#xff1f;它們的核心區別是什么&#xff1f; 專業解答&#xff1a; 進程是操作系統分配資源的基本單位&#xff0c;擁有獨立的內存空間&#xff1b;線程是進程內的執行單元&#xff0c;共享同一進程的資源。區別在于&#xff1a;進程間資源隔離…

考研408數據結構線性表核心知識點與易錯點詳解(附真題示例與避坑指南)

一、線性表基礎概念 1.1 定義與分類 定義&#xff1a;線性表是由n&#xff08;n≥0&#xff09;個相同類型數據元素構成的有限序列&#xff0c;元素間呈線性關系。 分類&#xff1a; 順序表&#xff1a;元素按邏輯順序存儲在一段連續的物理空間中&#xff08;數組實現&…

【實戰 ES】實戰 Elasticsearch:快速上手與深度實踐-1.2.2倒排索引原理與分詞器(Analyzer)

&#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 &#x1f449; 點擊關注不迷路 文章大綱 1.2.2倒排索引原理與分詞器&#xff08;Analyzer&#xff09;1. 倒排索引&#xff1a;搜索引擎的基石1.1 正排索引 vs 倒排索引示例數據對比&#xff1a; 1.2 倒排索引核心結…

Springboot項目本地連接并操作MySQL數據庫

目錄 前提 準備工作 用cmd在本地創建數據庫、表&#xff1a; 1.創建springboot項目&#xff08;已有可跳過&#xff09; 2.編輯Mybatis配置 3.連接數據庫 4.創建模型類&#xff0c;用于與數據庫里的數據表相連 5.創建接口mapper&#xff0c;定義對數據庫的操作 6.創建…