Java中使用Levenshtein距離實(shí)現(xiàn)字符串相似度匹配方式
在許多應(yīng)用中,我們需要根據(jù)用戶輸入的問題找到最匹配的已知問題。Levenshtein距離(編輯距離)是一個(gè)強(qiáng)大的工具,可以幫助我們衡量?jī)蓚€(gè)字符串之間的差異,并進(jìn)一步計(jì)算它們的相似度。
本文將使用一個(gè)具體的例子來展示如何在Java中實(shí)現(xiàn)這一功能,并詳細(xì)解釋每個(gè)步驟,使得初學(xué)者也能易于理解。
Levenshtein距離簡(jiǎn)介
Levenshtein距離是由俄羅斯科學(xué)家Vladimir Levenshtein在1965年提出的,用以量化兩個(gè)字符串之間的差異。
這種度量方式計(jì)算將一個(gè)字符串轉(zhuǎn)換成另一個(gè)字符串所需要的最少編輯操作次數(shù),包括插入、刪除和替換字符。
計(jì)算原理
Levenshtein距離的計(jì)算可以通過建立一個(gè)矩陣來完成:
- 初始化矩陣:創(chuàng)建一個(gè)(m+1)x(n+1)的矩陣,其中m和n是兩個(gè)字符串的長度。矩陣的第一行和第一列分別初始化為從0到m和0到n的序列,表示從空字符串到該長度的轉(zhuǎn)換所需的步驟。
- 填充矩陣:遍歷字符串,比較每個(gè)字符。如果字符相同,該位置的值為左上角的值;如果不同,取左(插入)、上(刪除)、左上(替換)三個(gè)方向的最小值加一。
- 獲取距離值:矩陣的最右下角的值即為兩字符串之間的Levenshtein距離。
相似度計(jì)算
通過Levenshtein距離,我們可以計(jì)算出兩個(gè)字符串的相似度,公式為:[ \text{相似度} = 1 - \frac{\text{Levenshtein距離}}{\max(\text{字符串A的長度}, \text{字符串B的長度})} ]這樣,相似度越接近1表示兩個(gè)字符串越相似。
在Java中的實(shí)現(xiàn)
首先,我們需要在Java項(xiàng)目中引入Apache Commons Lang庫,這個(gè)庫提供了計(jì)算Levenshtein距離的實(shí)用方法。
如果你的項(xiàng)目使用Maven進(jìn)行依賴管理,可以在pom.xml文件中添加以下依賴:
<!-- 在 Maven 的 pom.xml 文件中添加 Apache Commons Lang 依賴 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>接下來,我們將編寫一個(gè)Java類,其中包含一個(gè)方法來計(jì)算兩個(gè)字符串之間的相似度。
這個(gè)相似度是基于Levenshtein距離來計(jì)算的。
import org.apache.commons.lang3.StringUtils;
public class QuestionMatcher {
// 計(jì)算兩個(gè)字符串之間的相似度的方法
public static double calculateSimilarity(String input, String target) {
// 計(jì)算兩個(gè)字符串的最大長度
int maxLength = Math.max(input.length(), target.length());
// 使用StringUtils工具類計(jì)算Levenshtein距離
int editDistance = StringUtils.getLevenshteinDistance(input, target);
// 根據(jù)Levenshtein距離計(jì)算相似度
return 1.0 - (double) editDistance / maxLength;
}
public static void main(String[] args) {
// 用戶輸入的問題
String userQuestion = "如何煮雞蛋?";
// 已知的問題數(shù)組
String[] knownQuestions = {"如何煮沸雞蛋?", "如何煎雞蛋?", "如何剝雞蛋皮?"};
// 初始化最高相似度和最佳匹配問題
double highestSimilarity = 0;
String bestMatch = null;
// 遍歷已知問題,找到與用戶問題最相似的一個(gè)
for (String question : knownQuestions) {
double similarity = calculateSimilarity(userQuestion, question);
if (similarity > highestSimilarity) {
highestSimilarity = similarity;
bestMatch = question;
}
}
// 輸出最佳匹配的問題和其相似度
System.out.println("最佳匹配問題: " + bestMatch + ",相似度: " + highestSimilarity);
}
}輸出結(jié)果

解釋代碼
- calculateSimilarity方法:該方法接收兩個(gè)字符串參數(shù),計(jì)算它們之間的Levenshtein距離,并轉(zhuǎn)換成相似度。相似度計(jì)算公式是
1 - (編輯距離 / 最大字符串長度)。這樣得到的相似度越接近1,表示兩個(gè)字符串越相似。 - main方法:這是程序的入口。我們定義了一個(gè)用戶輸入的問題和一組已知問題。程序遍歷這些已知問題,計(jì)算每一個(gè)問題與用戶輸入問題之間的相似度,并找出相似度最高的問題作為最佳匹配。
總結(jié)
通過這個(gè)例子,我們可以看到Levenshtein距離是如何幫助我們?cè)趯?shí)際應(yīng)用中匹配用戶問題的。
這種方法不僅適用于問答系統(tǒng),還可以用于任何需要衡量文本相似度的場(chǎng)景,如搜索引擎優(yōu)化、數(shù)據(jù)清洗等。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)文件和base64流的相互轉(zhuǎn)換功能示例
這篇文章主要介紹了Java實(shí)現(xiàn)文件和base64流的相互轉(zhuǎn)換功能,涉及Java文件讀取及base64 轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2018-05-05
RxJava2.x+ReTrofit2.x多線程下載文件的示例代碼
本篇文章主要介紹了RxJava2.x+ReTrofit2.x多線程下載文件的示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09
詳解如何更改SpringBoot TomCat運(yùn)行方式
這篇文章主要介紹了詳解如何更改SpringBoot TomCat運(yùn)行方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
SpringBoot集成elasticsearch使用圖文詳解
Spring Boot集成Elasticsearch其實(shí)非常簡(jiǎn)單,這篇文章主要給大家介紹了關(guān)于SpringBoot集成elasticsearch使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04
詳解Java8新特性之interface中的static方法和default方法
這篇文章主要介紹了Java8新特性之interface中的static方法和default方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
JAVA中數(shù)組插入與刪除指定元素的實(shí)例代碼
下面小編就為大家分享一篇JAVA中數(shù)組插入與刪除指定元素的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-02-02
SpringMVC中Model和ModelAndView的EL表達(dá)式取值方法
下面小編就為大家分享一篇SpringMVC中Model和ModelAndView的EL表達(dá)式取值方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03
logback配置中變量和include的應(yīng)用方式
這篇文章主要介紹了logback配置中變量和include的應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08

