package com.datacloudsec.utils;

import org.apache.commons.lang.StringUtils;

/**
 * 文本相似度比较
 * @author Administrator
 */
public class ComputeTextUtil {
	
	private ComputeTextUtil(){
	}
	
	/**
	 * 获取两字符串的相似度
	 * @param str
	 * @param target
	 * @return
	 */
	public static double similarDegree(String str, String target) {
		boolean strBlank = StringUtils.isBlank(str);
		boolean targetBlank = StringUtils.isBlank(target);
		if(strBlank && targetBlank){
			return 1D;
		}
		if(strBlank || targetBlank){
			return 1D;
		}
		
		final int maxLen = Math.max(str.length(), target.length());
		int allowMaxLen = 7000;
		double num = 0D;
		double total = 0D;
		for(int i=0;i<maxLen;i+=allowMaxLen){
			int strIndex = Math.min(i+allowMaxLen,str.length());
			int targetIndex = Math.min(i+allowMaxLen,target.length());
			double tmpR;
			if(i >= strIndex || i >= targetIndex){
				tmpR = 0D;
			}else{
				String tmpStr = str.substring(i,strIndex);
				String tmpTarget = target.substring(i,targetIndex);
				tmpR = 1 - (double) compare(tmpStr, tmpTarget) / Math.max(tmpStr.length(), tmpTarget.length());
			}
			total += tmpR;
			num++;
		}
		return total / num;
	}
	
	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;
	}

	public static void main(String[] args) throws Exception {
		long l = System.currentTimeMillis();
		String str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac";
		String target = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac";
		System.out.println("similarityRatio=" + ComputeTextUtil.similarDegree(str,target));
		System.out.println("用时:" + (System.currentTimeMillis()-l));
	}
}
最近下载更多
gongjunjienb  LV15 2021年5月9日
whfuai  LV14 2021年2月1日
dengjunjun  LV15 2019年12月3日
WASDZZ  LV13 2018年12月29日
123456789ll  LV19 2018年8月23日
OwenLeon  LV9 2017年10月11日
最代码官方  LV168 2017年9月28日
murphyLu  LV12 2017年9月25日
helloMD  LV8 2017年9月25日
超度你  LV2 2017年9月23日
最近浏览更多
desdes  LV1 6月24日
hhsoft  LV1 2023年10月22日
炫瓶百事可乐  LV1 2022年12月1日
微信网友_6220678544494592  LV1 2022年11月18日
asdfasfasf 2022年10月30日
暂无贡献等级
好的好的  LV8 2022年7月11日
微信网友_5992582549164032  LV6 2022年6月29日
AngelW  LV10 2022年4月11日
有你的小镇 2021年12月22日
暂无贡献等级
ccxiao  LV2 2021年12月16日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友