首页 > 编程语言 >Java中对比两个字符串的相似度

Java中对比两个字符串的相似度

时间:2023-05-06 10:35:02浏览次数:38  
标签:Java String int return 字符串 strB strA 对比

Java中对比两个字符串的相似度的方法, 以下整理了两个方式比对方法,同样的字符串不同的计算方式得到的结果也是不同的:

package test;
 
/**
 * 对比俩个字符串的相似度
 * @author sanshi
 */
public class StrUtil {
    /**
     * 获取最长子串 (参数顺序与字符串长短无关)
     * @param strA
     * @param strB
     * @return
     */
    public static String longestCommonSubstringNoOrder(String strA, String strB) {
        if(strA.length() >= strB.length()){
            return longestCommonSubstring(strA, strB);
        }else{
            return longestCommonSubstring(strB, strA);
        }
    }
 
    /**
     * 获取最长子串 (长串在前,短串在后)
     * @param strLong
     * @param strShort
     * @return
     * <p>summary</p>:较长的字符串放到前面有助于提交效率
     */
    private static String longestCommonSubstring(String strLong, String strShort) {
        char[] chars_strA = strLong.toCharArray();
        char[] chars_strB = strShort.toCharArray();
        int m = chars_strA.length;
        int n = chars_strB.length;
        int[][] matrix = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (chars_strA[i - 1] == chars_strB[j - 1]){
                    matrix[i][j] = matrix[i - 1][j - 1] + 1;
                }
                else{
                    matrix[i][j] = Math.max(matrix[i][j - 1], matrix[i - 1][j]);
                }
            }
        }
        char[] result = new char[matrix[m][n]];
        int currentIndex = result.length - 1;
        while (matrix[m][n] != 0) {
            if (matrix[n] == matrix[n - 1]) {
                n--;
            } else if (matrix[m][n] == matrix[m - 1][n]) {
                m--;
            } else {
                result[currentIndex] = chars_strA[m - 1];
                currentIndex--;
                n--;
                m--;
            }
        }
        return new String(result);
    }
 
    private static boolean charReg(char charValue) {
        return (charValue >= 0x4E00 && charValue <= 0X9FA5) || (charValue >= 'a' && charValue <= 'z') || (charValue >= 'A' && charValue <= 'Z') || (charValue >= '0' && charValue <= '9');
    }
 
    private static String removeSign(String str) {
        StringBuffer sb = new StringBuffer();
        for (char item : str.toCharArray()){
            if (charReg(item)) {
                sb.append(item);
            }
        }
        return sb.toString();
    }
 
    /**
     * 比较俩个字符串的相似度(方式一)
     * 步骤1:获取两个串中最长共同子串(有序非连续)
     * 步骤2:共同子串长度 除以 较长串的长度
     * @param strA
     * @param strB
     * @return 两个字符串的相似度
     */
    public static double SimilarDegree(String strA, String strB) {
        String newStrA = removeSign(strA);
        String newStrB = removeSign(strB);
        int temp = Math.max(newStrA.length(), newStrB.length());
        int temp2 = longestCommonSubstringNoOrder(newStrA, newStrB).length();
        return temp2 * 1.0 / temp;
    }
 
    /**
     * 第二种实现方式 (获取两串不匹配字符数)
     * @param str
     * @param target
     * @return
     */
    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;
        }
        // 遍历str
        for (i = 1; i <= n; i++) {
            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;
    }
 
    /**
     * 比较俩个字符串的相似度(方式一)
     * 步骤1:获取两个串中不相同的字符数
     * 步骤2:不同字符数 除以 较长串的长度
     * @param strA
     * @param strB
     * @return
     */
    public static double similarityRatio(String strA, String strB) {
        return 1 - (double) compare(strA, strB) / Math.max(strA.length(), strB.length());
    }
 
 
    public static void main(String[] args){
        String strA = "河北唐山市协和医院";
        String strB = "河北省唐山协和医院";
 
        System.out.println(longestCommonSubstringNoOrder(strA,strB));
        System.out.println(SimilarDegree(strA,strB));
        System.out.println(compare(strA,strB));
        System.out.println(similarityRatio(strA,strB));
    }
 
}

示例代码输出结果如下:

河北唐山协和医院
0.8888888888888888
2
0.7777777777777778

 

标签:Java,String,int,return,字符串,strB,strA,对比
From: https://www.cnblogs.com/shuilangyizu/p/17376272.html

相关文章

  • 软硬件随机数对比
    本文对比C++中std::mt19937和硬件随机数效率。注意硬件随机数指令_rdrand32_step等属于AVX指令集。文档中说明_rdrand32_step可能会失败,失败时返回0,经过几次测试没有发现失败的情况。所以如果程序要求不严可以不管返回值。对比的结果是硬件随机数更慢。所以一般硬件随机数只产生一......
  • java -cp 错误:找不到或无法加载主类
    java-cp错误:找不到或无法加载主类1.问题场景在一个项目开发中,我需要写一个windows的bat脚本,需要在里面调用SpringBoot项目生成的jar包,我在调用classes下面的jar时通过调用jar包去调用jar包中的某个.java类总是报错误:找不到或无法加载主类最后搞的我心态都崩了,明......
  • 实践分享:打造极具高扩展性的JavaScript SDK
    SDK(SoftwareDeveloperKit)是使用FeatureProbe服务必不可少的工具之一。SDK能将用户的应用程序连接到FeatureProbe服务,根据用户的配置获取开关的结果,还能将开关的访问情况上报给FeatureProbe,进而实现A/B实验的能力。FeatureProbe目前对外提供十余种主流开发语言的SDK,包括......
  • Java实验十
    1importjava.io.*;2importjava.util.Arrays;3importjava.util.InputMismatchException;4importjava.util.Scanner;56publicclassAverageScore{7publicstaticvoidmain(String[]args)throwsIOException{8//System.out.println......
  • KNN中不同距离度量对比和介绍
    k近邻算法KNN是一种简单而强大的算法,可用于分类和回归任务。他实现简单,主要依赖不同的距离度量来判断向量间的区别,但是有很多距离度量可以使用,所以本文演示了KNN与三种不同距离度量(Euclidean、Minkowski和Manhattan)的使用。KNN算法概述KNN是一种惰性、基于实例的算法。它的工......
  • JavaWeb回顾与小结(六)
    项目实战-新增员工思路接收并封装参数,调用service方法保存数据,响应result@PostMapping@RequestBody补充实体基础属性,调用mapper接口进行保存数据操作insertintoemp(...)values(?,?,?);文件上传简介文件上传,指将本地图片,视频,音频等文件上传到服务器,供其他用......
  • 25基于java的在线考试系统
    一、项目简介随着互联网迅速发展,人们的生活已经越来越离不开互联网,人们足不出户就可以工作、买卖、学习等。对于在校学生,通过网络教育不仅可以随时进行网络学习,也可以根据学习的情况自我检测,有利于学生高效、快捷地掌握所学的知识。本系统预设计的基于网络的学生自测系统将实现......
  • java基于springboot+vue的校园新闻网站、校园新闻管理系统,附源码+数据库+文档+PPT,适合
    1、项目介绍校园新闻网站的主要使用者分为管理员和用户,实现功能包括管理员:首页、个人中心、用户管理、新闻类型管理、校园新闻管理、留言板管理、论坛交流、系统管理,用户前台:首页、校园新闻、论坛交流、留言反馈、个人中心、后台管理等功能。由于本网站的功能模块设计比较全面,所......
  • 常用的截取字符串方法JS和Golang实现
    JS中截取字符串很简单,直接使用substr函数substr()方法可在字符串中截取从开始下标开始的指定数目的字符。下标是从0开始算例如:"21".substr(0,1)  返回2golang实现的substr//截取字符串,支持多字节字符//start:起始下标,负数从从尾部开始,最后一个为-1//length:截取长度,......
  • 电子邮件系统 3----JavaMail POP3接收邮件示例 .
    1./**2.*CrazyItTest3.*使用JavaMail编写接收邮件示例4.*/5.package6.import7.import8.import9.import10.import11.import12.import13.import14.import15./**16.*@authorBillTu(tujiyue/iwtxokhtd)17.*May27,2011[10:04:20PM]18.......