zxl
2026-03-25 d1dfb6e35f38e27fd960dc3ad0130c8d0f5c39bb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.tievd.jyz.util;
 
import org.apache.commons.collections.map.HashedMap;
 
import java.util.Map;
 
/**
 * Author: wqy
 * Date: 2023/5/8 17:37
 */
public class StringCampareUtil {
    
    //相似等级 1严格相等 2相似 3加权相似
    public static int grade = 1;
    
    private static int perScore = 10;
    
    public static Map<Character, String> similarMap = new HashedMap();
    
    static {
        similarMap.put('A', "H41");
        similarMap.put('H', "A4N");
        similarMap.put('4', "AH1");
        similarMap.put('1', "17");
        similarMap.put('7', "1");
        similarMap.put('6', "890");
        similarMap.put('9', "860");
        similarMap.put('8', "96B");
        similarMap.put('B', "968");
        similarMap.put('2', "Z");
        similarMap.put('Z', "2");
        similarMap.put('0', "OQD");
        similarMap.put('O', "0QD");
        similarMap.put('D', "GO0Q");
        similarMap.put('G', "DO0Q");
        similarMap.put('Q', "DO0G");
        similarMap.put('M', "HNMW");
        similarMap.put('N', "HNM");
        similarMap.put('W', "NM");
    }
    
    //返回直接长度 当且仅当grade=1时使用
    public static int stringLCS(String str1, String str2) {
        return LCS(str1, str2) / perScore;
    }
    
    private static int LCS(String str1, String str2) {
        str1 = 0 + str1;
        str2 = 0 + str2;
        char[] charArr1 = str1.toCharArray();
        char[] charArr2 = str2.toCharArray();
        int len1 = charArr1.length;
        int len2 = charArr2.length;
        int lcs[][] = new int[len1][len2];
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                if (i == 0 || j == 0) {
                    lcs[i][j] = 0;
                } else {
                    int dVal = beSimilar(charArr1[i], charArr2[j]);
                    if (dVal > 0) {
                        lcs[i][j] = lcs[i - 1][j - 1] + dVal;
                    } else {
                        lcs[i][j] = Math.max(lcs[i][j - 1], lcs[i - 1][j]);
                    }
                }
            }
        }
        return lcs[len1 - 1][len2 - 1];
    }
    
    /**
     * 比较相似或相等
     * @param c1
     * @param c2
     * @return
     */
    private static int beSimilar(char c1, char c2) {
        if (c1 == c2) {
            return perScore;
        } else if (similarMap.getOrDefault(c1, "").contains("" + c2)) {
            switch (grade) {
                case 1: return 0;
                case 2: return perScore;
                case 3: return (int) (perScore*0.7);
            }
        }
        return 0;
    }
    
    /**
     * 根据grande等级,获取相似度百分值
     * @return
     */
    public static double scoreLCS(String str1, String str2) {
        int len = Math.min(str1.length(), str2.length());
        if (len==0) return 0;
        int lcs = LCS(str1, str2);
        return 1.0 * lcs / perScore /len;
    }
    
}