章
目
录
你知道Java中如何判断两个字符串之间的相似度,计算出它们的计算相似值吗?比如在问答系统里找匹配问题、博客中搜索文章、搜索引擎优化以及数据清洗等场景会经常遇到该问题。今天就给大家分享在Java里用Levenshtein距离实现字符串相似度匹配的方法。
一、Levenshtein距离定义
Levenshtein距离也叫编辑距离,是俄罗斯科学家弗拉基米尔·莱文斯坦在1965年提出来的,专门用来衡量两个字符串的差异程度。简单来说,就是计算把一个字符串变成另一个字符串,最少需要进行多少次插入、删除或替换字符的操作。知道了Levenshtein距离,就能算出两个字符串的相似度,相似度越接近1,说明两个字符串越相似。
二、Java代码实现Levenshtein距离计算
(一)引入依赖
在Java项目里用Levenshtein距离,得先引入Apache Commons Lang库,它提供了计算Levenshtein距离的实用方法。如果项目用Maven管理依赖,就在pom.xml
文件里添加下面这段依赖:
<!-- 在 Maven 的 pom.xml 文件中添加 Apache Commons Lang 依赖 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
(二)编写代码
下面写一个Java类,里面有个方法专门计算字符串相似度。
import org.apache.commons.lang3.StringUtils;
public class QuestionMatcher {
// 计算两个字符串之间的相似度的方法
public static double calculateSimilarity(String input, String target) {
// 计算两个字符串的最大长度
int maxLength = Math.max(input.length(), target.length());
// 使用StringUtils工具类计算Levenshtein距离
int editDistance = StringUtils.getLevenshteinDistance(input, target);
// 根据Levenshtein距离计算相似度
return 1.0 - (double) editDistance / maxLength;
}
public static void main(String[] args) {
// 用户输入的问题
String userQuestion = "如何煮鸡蛋?";
// 已知的问题数组
String[] knownQuestions = { "如何煮沸鸡蛋?", "如何煎鸡蛋?", "如何剥鸡蛋皮?"};
// 初始化最高相似度和最佳匹配问题
double highestSimilarity = 0;
String bestMatch = null;
// 遍历已知问题,找到与用户问题最相似的一个
for (String question : knownQuestions) {
double similarity = calculateSimilarity(userQuestion, question);
if (similarity > highestSimilarity) {
highestSimilarity = similarity;
bestMatch = question;
}
}
// 输出最佳匹配的问题和其相似度
System.out.println("最佳匹配问题: " + bestMatch + ",相似度: " + highestSimilarity);
}
}
测试结果如下图:
(三)代码解释
- calculateSimilarity方法:这个方法接收两个字符串参数,先算出它们的最大长度,再用
StringUtils
工具类计算Levenshtein距离,最后根据公式把距离转换成相似度。按照这个公式,得到的相似度越接近1,说明两个字符串越像。 - main方法:程序从这里开始执行。先定义了用户输入的问题和一组已知问题,然后遍历这些已知问题,每次都计算和用户输入问题的相似度。在遍历过程中,记录下相似度最高的问题和对应的相似度,最后输出最佳匹配的问题和它的相似度。
手写编辑距离计算算法
我们也可以自己手写一个编辑距离的算法,,常用于拼写检查或字符串匹配。代码如下:
public class LevenshteinDistance {
// 计算两个字符串之间编辑距离的方法
public static int calculate(String s1, String s2) {
// 创建一个二维数组dp,用于存储中间计算结果
int[][] dp = new int[s1.length() + 1][s2.length() + 1];
// 初始化第一行和第一列
for (int i = 0; i <= s1.length(); i++) {
for (int j = 0; j <= s2.length(); j++) {
if (i == 0) {
dp[i][j] = j;
} else if (j == 0) {
dp[i][j] = i;
} else if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
}
}
}
// 返回最终计算得到的编辑距离
return dp[s1.length()][s2.length()];
}
public static void main(String[] args) {
// 定义两个字符串
String s1 = "kitten";
String s2 = "sitting";
// 计算并输出这两个字符串的编辑距离
int distance = calculate(s1, s2);
System.out.println("编辑距离: " + distance);
}
}
calculate方法使用动态规划算法,通过填充二维数组dp来计算编辑距离,最后返回最右下角的值作为结果。
三、应用场景及总结
通过上面的例子,大家应该清楚Levenshtein距离在实际应用里是怎么匹配用户问题的了。这种基于Levenshtein距离计算字符串相似度的方法,应用场景可不止问答系统这一个。在搜索引擎优化时,可以用它判断搜索关键词和网页内容的相似度,提升搜索结果的精准度;数据清洗的时候,也能借助它发现和处理相似的重复数据。掌握了这个方法,在Java中处理字符串相似度开发时就可以轻松拿捏了。
当然,除了基于Levenshtein距离计算字符串相似度的方法外,还有其他一些算法可以实现文本字符串相似度判断,可以参考下文:
文章目录 一、相似度计算到底是什么? 二、Java实现相似度计算的开源库 三、相似度计算算法的Java实现 ( […]