字符串的模糊匹配方法介紹

字符串的模糊匹配方法介紹

目錄

  • 字符串的模糊匹配方法介紹
    • 一、編輯距離(Levenshtein Distance)
      • 復雜度分析
    • 二、Jaro-Winkler 距離
      • 復雜度分析
    • 三、最長公共子序列(LCS)
      • 復雜度分析
    • 四、模糊搜索(Fuzzy Search)
      • 復雜度分析
    • 五、正則表達式
      • 復雜度分析
    • 六、第三方庫
      • 復雜度分析
    • 總結

在日常開發和數據處理中,我們經常會遇到需要判斷兩個字符串是否“相似”或“接近”的場景,這時就需要用到字符串的模糊匹配。模糊匹配不同于精確匹配,它允許一定程度的誤差,比如拼寫錯誤、字符缺失等。下面介紹幾種常見的字符串模糊匹配方法。

一、編輯距離(Levenshtein Distance)

編輯距離是最常用的模糊匹配算法之一。它表示將一個字符串變換成另一個字符串所需的最少編輯操作次數。允許的操作包括插入、刪除和替換一個字符。編輯距離越小,兩個字符串越相似。

示例:

  • “kitten” 和 “sitting”的編輯距離為3(k→s,e→i,末尾加g)。

JavaScript代碼示例:

// 計算Levenshtein距離的簡單實現
function levenshtein(s1, s2) {const m = s1.length, n = s2.length;const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));for (let i = 0; i <= m; i++) dp[i][0] = i;for (let j = 0; j <= n; j++) dp[0][j] = j;for (let i = 1; i <= m; i++) {for (let j = 1; j <= n; j++) {if (s1[i - 1] === s2[j - 1]) {dp[i][j] = dp[i - 1][j - 1];} else {dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);}}}return dp[m][n];
}
console.log(levenshtein('kitten', 'sitting')); // 輸出: 3

復雜度分析

  • 時間復雜度:O(mn),其中 m 和 n 分別為兩個字符串的長度。
  • 空間復雜度:O(mn),需要一個 m×n 的二維數組。

二、Jaro-Winkler 距離

Jaro 距離和 Jaro-Winkler 距離主要用于短字符串(如人名)的相似度比較。它考慮了字符的順序和匹配字符之間的距離。Jaro-Winkler 在Jaro的基礎上增加了前綴加權,使得前綴相同的字符串相似度更高。

JavaScript代碼示例(使用jaro-winkler庫):

// 需先安裝 jaro-winkler: npm install jaro-winkler
const jaroWinkler = require('jaro-winkler');
console.log(jaroWinkler('MARTHA', 'MARHTA')); // 輸出: 0.961...

復雜度分析

  • 時間復雜度:O(n),n 為字符串長度(Jaro-Winkler 算法通常用于較短字符串,效率較高)。
  • 空間復雜度:O(n)。

三、最長公共子序列(LCS)

最長公共子序列是指在不改變字符順序的前提下,兩個字符串中最長的公共子序列。LCS長度越長,字符串越相似。常用于DNA序列比對等場景。

JavaScript代碼示例:

// 計算最長公共子序列長度
function lcs(s1, s2) {const m = s1.length, n = s2.length;const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));for (let i = 1; i <= m; i++) {for (let j = 1; j <= n; j++) {if (s1[i - 1] === s2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[m][n];
}
console.log(lcs('abcdef', 'acbcf')); // 輸出: 4

復雜度分析

  • 時間復雜度:O(mn),m 和 n 為兩個字符串的長度。
  • 空間復雜度:O(mn)。

四、模糊搜索(Fuzzy Search)

模糊搜索常用于搜索引擎和自動補全。常見實現有:

  • Trie樹結合模糊匹配
  • BK-Tree(Burkhard-Keller Tree),適合大規模字符串集合的模糊查找
  • SimHash、MinHash等哈希算法,用于大規模文本的相似性檢測

JavaScript代碼示例(使用fuse.js庫):

// 需先安裝 fuse.js: npm install fuse.js
const Fuse = require('fuse.js');
const list = ['apple pie', 'banana', 'pineapple', 'apple', 'apricot'];
const fuse = new Fuse(list, { includeScore: true });
const result = fuse.search('apple pi');
console.log(result);

復雜度分析

  • Trie樹:構建時間 O(NL),查詢時間 O(L),N 為詞條數,L 為平均長度。
  • BK-Tree:查詢時間與誤差閾值和數據分布有關,通常遠優于暴力搜索。
  • SimHash/MinHash:構建和查詢均為 O(L),L 為文本長度。
  • fuse.js(基于模糊搜索):O(NL),N 為數據量,L 為關鍵詞長度。

五、正則表達式

正則表達式可以實現簡單的模糊匹配,比如用通配符匹配部分字符,但它不適合復雜的相似度計算。

JavaScript代碼示例:

const pattern = /ap.le/;
const text = 'apple';
if (pattern.test(text)) {console.log('匹配成功'); // 輸出: 匹配成功
}

復雜度分析

  • 時間復雜度:O(n),n 為文本長度(正則表達式引擎實現不同,部分復雜模式可能更高)。
  • 空間復雜度:O(1)。

六、第三方庫

許多編程語言都提供了現成的模糊匹配庫。例如:

  • Python:fuzzywuzzy、difflib
  • JavaScript:fuse.js、jaro-winkler
  • Java:Lucene

JavaScript difflib 類似實現(使用string-similarity庫):

// 需先安裝 string-similarity: npm install string-similarity
const stringSimilarity = require('string-similarity');
const s1 = 'hello world';
const s2 = 'helo wrld';
console.log(stringSimilarity.compareTwoStrings(s1, s2)); // 輸出: 0.909...

復雜度分析

  • fuzzywuzzy/difflib(Python):O(mn)
  • string-similarity(JS):O(mn)
  • fuse.js(JS):O(NL)
  • Lucene(Java):倒排索引,查詢效率高,通常遠優于 O(N)

總結

字符串的模糊匹配方法多種多樣,選擇合適的方法取決于具體的應用場景和性能需求。對于小規模、精度要求高的場景,可以使用編輯距離、Jaro-Winkler等算法;對于大規模數據檢索,可以考慮BK-Tree、SimHash等高效算法。掌握這些方法,有助于提升文本處理和搜索的智能化水平。

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

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

相關文章

ActiveMQ在Spring Boot中的詳細使用指南

?? 目錄 ?? ActiveMQ簡介 什么是ActiveMQ? 核心概念 ??? 基礎架構組件 ?? 重要概念解釋 ActiveMQ vs 其他消息中間件 ?? 環境搭建 1. ActiveMQ服務端安裝 Docker方式(推薦初學者) 手動安裝方式 2. 驗證安裝 訪問Web管理界面 連接參數 測試連接 ?…

二元一次方程

前言 最近剛學二元一次方程&#xff0c;想寫一篇專欄熟悉一下本文寫給初一的同學看&#xff0c;學過的就劃了吧二元一次方程 兩個未知數最高項次數為 111 次為整式方程二元一次方程的解不唯一&#xff0c;但是二元一次方程可以用一個未知數來表達另一個未知數eg:eg:eg: xy1x y…

AI編程的未來是智能體原生開發?

目錄 前言 一、從“串行”到“并行”&#xff1a;什么是智能體原生開發&#xff1f; 1.1 傳統模式&#xff08;串行思維&#xff09; 1.2 智能體原生模式&#xff08;并行思維&#xff09; 二、程序員的新角色&#xff1a;從代碼手藝人到系統思想家 三、軟件開發的終局&a…

【牛客刷題】小紅的與運算

文章目錄 一、題目介紹1.1 題目描述1.2 輸入描述1.3 輸出描述1.4 示例二、 解題思路2.1 核心算法設計2.2 性能優化關鍵2.3 算法流程圖三、解法實現3.1 解法一:基礎實現3.1.1 初級版本分析3.2 解法二:優化版本(推薦)3.2.1 優化版本分析四、總結與拓展4.1 關鍵優化技術4.2 算…

spring中 方法上@Transation實現原理

Spring中Transactional注解方法實現原理Spring的Transactional注解在方法級別實現事務管理的原理主要基于動態代理和攔截器機制&#xff0c;以下是其核心實現流程&#xff1a;1. 代理創建階段當Spring容器啟動時&#xff0c;會為帶有Transactional注解的類創建代理對象&#xf…

qt-C++語法筆記之Stretch與Spacer的關系分析

qt-C語法筆記之Stretch與Spacer的關系分析 code review! 文章目錄qt-C語法筆記之Stretch與Spacer的關系分析1. Stretch&#xff08;拉伸因子&#xff09;2. Horizontal Spacer 和 Vertical Spacer3. Stretch 和 Spacer 的關系4. 實際應用中的選擇5. 注意事項6. 代碼與 Qt Desig…

Qwen3技術綜述

1. 引入 2025年5月&#xff0c;qwen推出了旗艦模型&#xff08;flagship model&#xff09;Qwen3-235B-A22B。并以Apache 2.0版權發布&#xff08;可自由商業使用&#xff0c;修改代碼和商用要包含原始版權&#xff09;。本文對其技術報告中提到的數據處理技術與模型結構進行綜…

[特殊字符] Excel 讀取收件人 + Outlook 批量發送帶附件郵件 —— Python 自動化實戰

許多公司定期需要將不同部門或客戶的報告發送給指定人員。手動操作容易出錯、耗時且繁瑣。今天這篇文章教你如何利用 Python 實現&#xff1a; &#x1f9e9; 從 Excel 中讀取“收件人 抄送人 附件文件路徑”&#xff1b; &#x1f4e4; 使用 win32com.client 調用 Outlook …

多模態大語言模型arxiv論文略讀(152)

VidComposition: Can MLLMs Analyze Compositions in Compiled Videos? ?? 論文標題&#xff1a;VidComposition: Can MLLMs Analyze Compositions in Compiled Videos? ?? 論文作者&#xff1a;Yunlong Tang, Junjia Guo, Hang Hua, Susan Liang, Mingqian Feng, Xinya…

基于AR和SLAM技術的商場智能導視系統技術原理詳解

本文面對室內定位算法工程師、智慧商場系統開發者、對VR/AR應用開發感興趣的技術人員&#xff0c;解決如何通過SLAMAR技術破解大型商場室內導航的空間認知壁壘&#xff0c;實現沉浸式導覽&#xff0c;本文提供完整技術方案與代碼實現。 如需獲取商場智能導視系統解決方案請前往…

Debezium日常分享系列之:認識Debezium Operator

Debezium日常分享系列之&#xff1a;認識Debezium Operator什么是Debezium OperatorDebezium Operator 的工作原理Debezium Operator 的優點Debezium Operator 使用場景Debezium Operator 的關鍵組件部署Debezium OperatorDebezium Operator 的使用什么是Debezium Operator De…

POSIX信號量,環形隊列

是一種進程間或線程間同步機制&#xff0c;用于控制多個線程/進程對共享資源的訪問&#xff0c;避免并發沖突。可以看作是一個計數器&#xff0c;通過對計數器的操作&#xff08;PV操作&#xff09;實現同步P操作(原子性)&#xff1a;&#xff0d;&#xff0d;&#xff0c;將信…

Python Day6

浙大疏錦行 Python Day6 內容&#xff1a; 描述性統計&#xff08;可視化分析&#xff09;單特征可視化&#xff08;連續、離散&#xff09;特征與標簽可視化特征與特征可視化 代碼&#xff1a; # TODO: 描述性統計 import pandas as pd import numpy as np import seaborn…

ESP32與樹莓派C++、Rust開發實戰

C++語言在ESP32、樹莓派實例 以下是關于C++語言在ESP32、樹莓派等硬件設備上的開發實例匯總,涵蓋常見應用場景和代碼示例。 ESP32開發實例 LED控制(GPIO操作) 使用ESP32的GPIO控制LED燈,示例代碼基于Arduino框架: #include <Arduino.h> const int ledPin = 2; …

Jedis 原生之道:Redis 命令 Java 實現指南(一)

Hi~&#xff01;這里是奮斗的明志&#xff0c;很榮幸您能閱讀我的文章&#xff0c;誠請評論指點&#xff0c;歡迎歡迎 ~~ &#x1f331;&#x1f331;個人主頁&#xff1a;奮斗的明志 &#x1f331;&#x1f331;所屬專欄&#xff1a;Redis &#x1f4da;本系列文章為個人學習筆…

飛算 JavaAI 開發助手:深度學習驅動下的 Java 全鏈路智能開發新范式

飛算 JavaAI 開發助手&#xff1a;深度學習驅動下的 Java 全鏈路智能開發新范式 文章目錄飛算 JavaAI 開發助手&#xff1a;深度學習驅動下的 Java 全鏈路智能開發新范式前言飛算 JavaAI IDEA插件下載、注冊、使用智能引導操作流程Java Chat智能工作流程操作流程智能問答操作流…

Spring Boot 核心特性與版本演進解析

深度解讀自動配置原理、版本差異與 3.x 的顛覆性變革 一、Spring Boot 的核心理念與迭代主線 Spring Boot 用兩大核心武器重構了 Java 開發范式&#xff1a; 嵌入式容器&#xff1a;終結了 “war 包 Tomcat 配置地獄”&#xff0c;讓 java -jar 成為生產級部署的標準姿勢自動…

React Tailwind css 大前端考試、問卷響應式模板

功能概述 基于 React 和 Tailwind CSS 開發的在線大前端知識考試系統。頁面設計簡潔美觀&#xff0c;交互流暢&#xff0c;適合前端開發者、學習者進行自我測試和知識鞏固。系統內置多道涵蓋 React、CSS、JavaScript、HTTP 等前端核心知識點的題目&#xff0c;支持單選與多選題…

【前端】手寫代碼匯總

近期更新完&#xff0c;后面不定期更新&#xff0c;建議關注收藏點贊。 目錄快排手寫防抖節流數組扁平化&#xff08;要求使用 reduce 方法&#xff09;數組filter實現手寫一個加載圖片的函數 loadImage手寫Promise then手寫 Promise.All手寫 Promise.race手寫allsettled手寫us…

基于MATLAB 的心電信號去噪

基于Matlab的心電信號去噪 generate.m , 3450 genR.m , 953 genU.m , 891 get_obs.m , 957 CHANGELOG , 11185 find_localobs.m , 2312 fmain.m , 2272