编辑距离
2021-02-22 本文已影响0人
kevinfuture
/**
* 给出字符串:str1、str2;判断这两个字符串的相似度有多大;
* 编辑距离:可通过增删改,将str1操作某一或某几个字符转换成str2,其中改变最小的距离,为最优。
* Dp规划实现编辑距离的相似度测算
* 空间复杂度:O(mn)
* 时间复杂度:O(mn)
* @author Administrator
*/
public class EditDistanceUtils {
/**
* Dp规划实现的编辑距离
* 步骤:
* 1、构建一个二维数组;
* 2、初始化input、target中每个字符的索引位置,分别初始化值的位置是第一行与第一列,表示input与target;
* 3、根据判断,算出对应二维数组坐标处对应的编辑距离;(这里的距离,就是距离目标的字符的索引数值差)
* 4、最后的对角值即为最终编辑距离的结果
* **/
private static int getEditDistance(String input, String target){
try {
int m = input.length();
int n = target.length();
if(m <= 0){
return n;
}
if(n <= 0){
return m;
}
//构建二维数组,并初始化
int[][] matrix = new int[m][n];
for(int i = 0; i < m; ++i){
matrix[i][0] = i;
}
for(int i = 0; i < n; ++i){
matrix[0][i] = i;
}
//遍历整个二维数组,获取每个字符所在位置的编辑距离;因为要计算i-1、j-1的位置,故从i/j=1开始
for(int i = 1; i < m; ++i){
for(int j = 1; j < n; ++j){
int c = input.charAt(i) == target.charAt(j) ? 0 : 1;
//i-1、j-1是算上一个交叉点的位置坐标;i-1、j与i、j-1为相邻两侧,从索引处已经减1,故加1
matrix[i][j] = Math.min(matrix[i-1][j-1] + c, Math.min(matrix[i -1][j] + 1, matrix[i][j - 1] + 1));
}
}
return matrix[m - 1][n - 1];
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
/**
* 计算两个字符串的 相似度
* **/
public static Double getSimilarity(String input, String target){
Integer distance = getEditDistance(input, target);
Double similarity = 1 - distance.doubleValue() / Math.max(input.length(), target.length());
return similarity;
}
/**
* 计算输入字符串,与其他多个字符串的相似度
* **/
public static Map<String, Double> getSimilarityMap(String input, String... targets){
try{
if(input.length() <= 0){
return Collections.EMPTY_MAP;
}
if(targets == null || targets.length <= 0){
return Collections.EMPTY_MAP;
}
LinkedHashMap<String,Double> linkedHashMap = new LinkedHashMap<>();
String target = "";
for(int i = 0; i < targets.length; ++i){
target = targets[i];
Double similarity = getSimilarity(input, target);
linkedHashMap.put(target, similarity);
}
return linkedHashMap;
}catch (Exception e){
e.printStackTrace();
}
return Collections.EMPTY_MAP;
}
/**
* 计算输入字符串,与其他多个字符串的相似度
* **/
public static Map<String, Double> getSimilarityMap(String input, Double limit, String... targets){
try{
Map<String, Double> linkedHashMap = getSimilarityMap(input, targets);
List<String> keyList = linkedHashMap.keySet().stream().collect(Collectors.toList());
LinkedHashMap<String, Double> limitMap = new LinkedHashMap<>();
String key = "";
Double value = 0D;
for(int i = 0; i < keyList.size(); ++i){
key = keyList.get(i);
value = linkedHashMap.getOrDefault(key, 0D);
if(value >= limit){
limitMap.put(key, value);
}
}
return limitMap;
}catch (Exception e){
e.printStackTrace();
}
return Collections.EMPTY_MAP;
}
public static void main(String[] args) {
getSimilarityMap("haizeiwang", 0.8D,"haizhughaiwang","haizaiwang","haizaiwatg");
}
}