你知道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); } } 

测试结果

(三)代码解释

  1. calculateSimilarity方法:这个方法接收两个字符串参数,先算出它们的最大长度,再用StringUtils工具类计算Levenshtein距离,最后根据公式把距离转换成相似度。按照这个公式,得到的相似度越接近1,说明两个字符串越像。
  2. 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距离计算字符串相似度的方法外,还有其他一些算法可以实现文本字符串相似度判断,可以参考下文: