java代码比较两个字符串的相似程度

本文介绍了一种计算两个字符串相似度的方法,并提供了详细的Java实现代码。该算法通过比较两个字符串之间的差异来确定它们的相似程度,返回一个介于0.0到1.0之间的浮点数,其中1.0表示两个字符串完全相同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码,相信你一看就会用。

public class Test {

    public static void main(String[] args) {

        String str = "返回死哦的话 感受到佛光 对方答复i夫vif夫和vfdhv 好好 vhfovh0ryf 后 vajs的";
        String target = "时候 地方 焦点网 资金到位欧豪【吃哦继续吃点【删除你的VC第【才的vahspdi[i";
        float similarity = getSimilarityRatio(str, target);
        System.out.println(similarity);

    }

    /***
     * 完全相似=1.0
     * 完全不相似=0.0
     */
    public static float getSimilarityRatio(String str, String target) {
        return 1 - (float) compare(str, target) / Math.max(str.length(), target.length());
    }

    private static int compare(String str, String target) {
        int d[][]; // 矩阵
        int n = str.length();
        int m = target.length();
        int i; // 遍历str的
        int j; // 遍历target的
        char ch1; // str的
        char ch2; // target的
        int temp; // 记录相同字符,在某个矩阵位置值的增量,不是0就是1
        if (n == 0) {
            return m;
        }
        if (m == 0) {
            return n;
        }
        d = new int[n + 1][m + 1];
        for (i = 0; i <= n; i++) { // 初始化第一列
            d[i][0] = i;
        }

        for (j = 0; j <= m; j++) { // 初始化第一行
            d[0][j] = j;
        }

        for (i = 1; i <= n; i++) { // 遍历str
            ch1 = str.charAt(i - 1);
            // 去匹配target
            for (j = 1; j <= m; j++) {
                ch2 = target.charAt(j - 1);
                if (ch1 == ch2) {
                    temp = 0;
                } else {
                    temp = 1;
                }

                // 左边+1,上边+1, 左上角+temp取最小
                d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + temp);
            }
        }
        return d[n][m];
    }

    private static int min(int one, int two, int three) {
        return (one = one < two ? one : two) < three ? one : three;
    }
}
<think>我们被要求用Java编写一个计算两个字符串相似的程序。根据引用[2]和[3],我们可以使用编辑距离(Levenshtein距离)算法来实现。编辑距离是指将一个字符串转换成另一个字符串所需的最少单字符编辑(插入、删除或替换)次数。相似可以通过编辑距离计算得出,例如:相似 = 1 - (编辑距离 / 两个字符串的最大长) 步骤: 1. 实现Levenshtein距离算法。 2. 根据编辑距离计算相似分数(0到1之间,1表示完全相同)。 注意:对于非常大的字符串,其他算法可能更合适,但Levenshtein距离对于一般情况是足够的。 我们将编写一个函数来计算两个字符串的Levenshtein距离,然后利用这个距离计算相似。 Levenshtein距离算法使用动态规划。我们创建一个二维数组dp,其中dp[i][j]表示字符串str1的前i个字符和字符串str2的前j个字符之间的编辑距离。 递推关系: - 如果i=0,则dp[0][j] = j(将空字符串变为str2的前j个字符需要j次插入) - 如果j=0,则dp[i][0] = i(将str1的前i个字符变为空字符串需要i次删除) - 如果str1的第i个字符等于str2的第j个字符,则dp[i][j] = dp[i-1][j-1] - 否则,dp[i][j] = min(dp[i-1][j] + 1, // 删除 dp[i][j-1] + 1, // 插入 dp[i-1][j-1] + 1) // 替换 然后,相似可以这样计算:similarity = 1 - (dp[m][n] / max(m, n)),其中m和n分别是两个字符串的长。注意,当两个字符串都为空时,max(m,n)为0,此时相似应为1(定义相同)。 我们也可以使用其他相似计算公式,例如:similarity = (maxLength - editDistance) / maxLength,其中maxLength是两字符串的最大值。 现在,我们编写代码:</think>以下是一个使用 Java 实现字符串相似计算的程序,基于 Levenshtein 距离算法(编辑距离算法): ```java public class StringSimilarity { public static void main(String[] args) { String str1 = "kitten"; String str2 = "sitting"; double similarity = calculateSimilarity(str1, str2); System.out.println("字符串相似: " + String.format("%.2f", similarity * 100) + "%"); } /** * 计算两个字符串相似(基于编辑距离) * @param str1 第一个字符串 * @param str2 第二个字符串 * @return 相似分数 (0.0 - 1.0) */ public static double calculateSimilarity(String str1, String str2) { int maxLength = Math.max(str1.length(), str2.length()); if (maxLength == 0) return 1.0; // 两个字符串视为100%相似 int editDistance = computeLevenshteinDistance(str1, str2); return 1.0 - (double) editDistance / maxLength; } /** * 计算两个字符串的 Levenshtein 距离(编辑距离) * @param str1 第一个字符串 * @param str2 第二个字符串 * @return 编辑距离值 */ private static int computeLevenshteinDistance(String str1, String str2) { int m = str1.length(); int n = str2.length(); int[][] dp = new int[m + 1][n + 1]; // 初始化基础情况 for (int i = 0; i <= m; i++) dp[i][0] = i; for (int j = 0; j <= n; j++) dp[0][j] = j; // 动态规划计算编辑距离 for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { int cost = (str1.charAt(i - 1) == str2.charAt(j - 1)) ? 0 : 1; dp[i][j] = Math.min( Math.min(dp[i - 1][j] + 1, // 删除操作 dp[i][j - 1] + 1), // 插入操作 dp[i - 1][j - 1] + cost // 替换操作 ); } } return dp[m][n]; } } ``` ### 算法说明: 1. **Levenshtein 距离**:计算将一个字符串转换为另一个字符串所需的最少单字符编辑操作次数(插入、删除或替换)[^2]。 2. **相似计算**:相似分数 = $1 - \frac{\text{编辑距离}}{\max(\text{len}(str1), \text{len}(str2))}$ - 当两个字符串完全相同时,分数为 1.0 - 当两个字符串完全不同时,分数接近 0.0 3. **动态规划**:使用二维数组 `dp` 存储子问题的解,时间复杂为 $O(m \times n)$,空间复杂为 $O(m \times n)$ ### 示例输出: ``` 字符串相似: 57.14% ``` ### 优化建议: 1. **大字符串处理**:对于超长字符串,可使用滚动数组优化空间复杂至 $O(\min(m, n))$ 2. **相似阈值**:添加阈值判断,当编辑距离超过阈值时提前终止计算 3. **其他算法**: - Jaro-Winkler 距离(对前缀相似更敏感) - Cosine 相似(适用于词袋模型) - 最长公共子序列(LCS)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值