【算法】编辑距离相似度算法

Levenshtein.java

/**
 * 算法原理
 * 编辑距离
 * Levenshtein distance最先是由俄国科学家Vladimir Levenshtein在1965年发明,用他的名字命名。不会拼读,可以叫它edit distance(编辑距离)。 
 * 原理很简单,就是返回将第一个字符串转换(删除、插入、替换)成第二个字符串的编辑次数。次数越少,意味着字符串相似度越高 
 * Spell checking(拼写检查) 
 * Speech recognition(语句识别) 
 * DNA analysis(DNA分析) 
 * Plagiarism detection(抄袭检测) 
 * LD用m*n的矩阵存储距离值。算法大概过程: 
 * @author Administrator
 *
 */
public class Levenshtein
{
    private 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 || ch1 == ch2+32 || ch1+32 == ch2)
                {
                    temp = 0;
                } else
                {
                    temp = 1;  
                }
//                System.out.println(ch1+" "+ch2+" "+temp);
                // 左边+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 int min(int one, int two, int three)
    {
        return (one = one < two ? one : two) < three ? one : three;
    }

    /**
     * 获取两字符串的相似度
     */

    public float getSimilarityRatio(String str, String target)
    {
//        System.out.println("-------------------------compare------------------------------------");
//        System.out.println("str1:"+str);
//        System.out.println("str2:"+target);
        int len=compare(str, target);
//        System.out.println("字符串距离:"+len);
        if(Math.max(str.length(), target.length())==0){
            return 1;
        }
        return 1 - (float) len / Math.max(str.length(), target.length());
    }


    /**
     * 获取两字符串的相似度 按最短字符串比较
     */

    public float getSimilarityRatioMin(String str, String target)
    {
        System.out.println(str+"    "+target);
        if(Math.min(str.length(), target.length())==0){
            return 1;
        }
        int len=compare(str, target);
//        System.out.println("字符串距离:"+len);
        return 1 - (float) len / Math.min(str.length(), target.length());
    }

    public static void main(String[] args)
    {

        Levenshtein lt = new Levenshtein();
        String str = "中华人民共和国人民币";
        String target = "中华人民共和国";
        System.out.println("similarityRatio=" + lt.getSimilarityRatio(str, target));
    }
}

QuestSimilarityUtil.java


import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class QuestSimilarityUtil {

    public static String clearHtmlTag(String str,boolean sort) {
        if (str != null && str.length() > 0) {
            str=clearWiteSpace(str);
            if(sort){
                str=reSortString(str);
            }

            return str;
        }
        return str;
    }

    public static String clearWiteSpace(String str) {
        if (str != null && str.length() > 0) {
            str = str.replaceAll("\\s*", "");// 去掉所有空格,包括首尾,中间
            str = str.replaceAll("\\u00A0", "");// 中文空格 对应页面中的:&nbsp;
            str = str.replaceAll("[\\pP\\p{Punct}]", "");// 清除所有符号,只留下字母 数字 汉字 共3类.
            return str;
        }
        return str;
    }

    /**
     * 字符串无需
     * @param str
     * @return
     */
    public static String reSortString(String str) {
        if (str == null || str.length() == 0) {
            return str;
        }
        char[] s1 = str.toCharArray();
        for (int i = 0; i < s1.length; i++) {
            for (int j = 0; j < i; j++) {
                if (s1[i] < s1[j]) {
                    char temp = s1[i];
                    s1[i] = s1[j];
                    s1[j] = temp;
                }
            }
        }
        // 再次将字符数组转换为字符串,也可以直接利用String.valueOf(s1)转换
        String st = new String(s1);
        return st;
    }

    //相似度,字符串进行无序比对
    public static float sim(String str1, String str2) {
        try{
            str1 = clearHtmlTag(str1,true);
            str2 = clearHtmlTag(str2,true);

//            System.out.println(str1);
//            System.out.println(str2);
            Levenshtein lt = new Levenshtein();
            float sm = lt.getSimilarityRatio(str1, str2);
            return sm;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0f;
    }
    public static float sim3(String str1, String str2) {
        try{
            str1 = clearHtmlTag(str1,true);
            str2 = clearHtmlTag(str2,true);

//            System.out.println(str1);
//            System.out.println(str2);
            Levenshtein lt = new Levenshtein();
            float sm = lt.getSimilarityRatioMin(str1, str2);
            return sm;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0f;
    }
    //相似度,字符串进行有序比对
    public static float sim2(String str1, String str2) {
        try{
            str1 = clearHtmlTag(str1,false);
            str2 = clearHtmlTag(str2,false);

//            System.out.println(str1);
//            System.out.println(str2);
            Levenshtein lt = new Levenshtein();
            float sm = lt.getSimilarityRatio(str1, str2);
            return sm;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0f;
    }

    public static boolean isLaji(String str){
        String reg=".*([0-9a-zA-Z\u4e00-\u9fa5]+).*";
        Pattern p = Pattern.compile(reg);
        Matcher m  = p.matcher(str);
        return m.find();
    }
    public static void main(String[] args) {
        // clearWiteSpace("A.蔗糖    B.食盐    C.小苏打    D.食醋 ");
        String str1 = "11.【中考·牡丹江】某种商品的进价为每件100元,商 16.【中考·贵阳】某文具店最近有A,B两款毕业纪念 场按进价提高50%后标价,为增加销量,准备打折销 册比较畅销,近两周的销售情况是第一周A款销售 售,但要保证利润率不低于20%,则至多可以打 数量是15本,B款销售数量是10本,销售总价是 _折. 230元:第二周A款销售数量是20本,B款销售数量 12.若关于x的一元一次不等式组 \\left\\{\\begin{array}{l}3-2x>2,\\\\x-a>0\\end{array}\\right. 是10本,销售总价是280元. 有3个整 (1)求A,B两款毕业纪念册的销售单价; 数解,则a的取值范围是. (2)若某班准备用不超过529元购买这两种款式的毕业 13.若x为有理数,则[x]表示不大于x的最大整数,例 纪念册共60本,求最多能够买多少本A款毕业纪 如 [1.6]=1,[π]=3,[-2.82]=-3 等. [x]+1 念册. 是大于x的最小整数,对任意的有理数x都满足不 等式组 [x]≤x<[x]+1. 利用这个不等式组,求出 满足 [x]=2x-1 1的所有解,其所有解为. 三、解答题 14.解下列不等式(组).并把它们的解集在数轴上表示 出来. \\left(1\\right)\\frac{2x-1}{3}\\le\\frac{3x+2}{4}-1; 17.【中考·福建】某工厂为贯彻落实“绿水青山就是 金山银山”的发展理念,投资组建了日废水处理量为 m吨的废水处理车间,对该厂工业废水进行无害化 处理.但随着工厂生产规模的扩大,该车间经常无法 完成当天工业废水的处理任务,需要将超出日废水 (2)【中考·江西】 \\left\\{\\begin{array}{l}2\\left(x+1\\right)>x,\\\\1-2x\\ge\\frac{x+7}{2}.\\end{array}\\right. 处理量的废水交给第三方企业处理.已知该车间处 理废水,每天需固定成本30元,并且每处理一吨废 水还需其他费用8元;将废水交给第三方企业处理, 每吨需支付12元.根据记录,5月21日,该厂产生工 业废水35吨,共花费废水处理费370元. (1)求该车间的日废水处理量 m; 3x<5x+6, (2)为实现可持续发展,走绿色发展之路,工厂合理控制 15.【中考·遂宁】解不等式组 \\left\\{\\begin{array}{l}\\frac{x+1}{6}+1\\le0,\\\\\\frac{x+1}{6}\\ge\\frac{x-1}{2},\\end{array}\\right. 把它的解 了生产规模,使得每天废水处理的平均费用不超过 10元/吨,试计算该厂一天产生的工业废水量的 集在数轴上表示出来,并写出其整数解. 范围. 期末提分练案 条案/ 111 本页答案及点拨见145页\n";
        String str2 = "\n" +
                "第5课时一元一次不等式 11.【中考·牡丹江】某种商品的进价 场按进价提高50%后标价,为增加销 一考点梳理! 售,但要保证利润率不低于20% 1.不等式的两边都加上(或都减去) 3-2 同一个教或同一个整式,不等号好 12.若关于x的一元一次不等式组 x 不等式 方向不变 不等式 不等式的解 2.不等式的两边都乘从(或都除从) 数解,则的取值范围是. 的性质 不等式的解集 同一个正数,不等号的方向不变 概念 13.若x为有理数,则[ [x] ]表示不大于x的 一元一次不等式 3.不等式的两边都乘以(或都除以 同一个数,不等号的方向改变 如[ [1.6]=1,[π]=3,[-2.82]=-3 一元-次不等式组 一元一次不等式姐的解集 元一次 去分母 是大于x的最小整数,对任意的有理数 等式组[ x]≤x<[x]+1. .利用这个不等 每个不等式的解集,监 不等式 解一元一 去括号 D利用教轴找出解集的 次不等式 移项 满足 [x]=2x-1 的所有解,其所有解为 公共部分 合并同类项 解一元一次 三、解答题 不等式组 系数化为! 同大取大,同小取小 14.解下列不等式(组).并把它们的解集在券 大小小大中间找,大大 一 小小找不列 用 )一元一次不等式 出来. 解决实际间题 \\left(1\\right)\\frac{2x-1}{3}\\le\\frac{3x+2}{4}-1; 达标训练 一、选择题 1.已知四个有理数a,b,c,d,若 a>b,c>d, 省30元,直到她至少存有1080元,设x个月后小丽 A.a+c>b+d B.a-c>b-d 有1080元,则可列计算月数的不等式为 为() A.30x+750>1080 C.ac>bd D.\\frac{a}{c}>\\frac{b}{d} C.30x-750≤1080 B.30x~750≥1080 D.30x+750≥1080 2.【中考·襄阳】不等式组 且 2x<x+4, 7.【中考·德州】不等式组 5x+33(x-1), 5x+3>3(x-1), (2)【中考·江 {3+x≥3x+9\\right. 的解集在数轴 x-1\\le7-\\frac{3}{2}x 的所有 则\\left\\{\\begin{array}{l}2\\left(x+1\\right)>x,\\\\1-2x\\ge\\frac{x+7}{2}.\\end{array}\\right. 上用阴影表示正确的是 () 非负整数解的和是 B. A.10 30 C.6 D.0 D. \\overrightarrow{0} \\frac{1}{-30} 8.【中考·呼和浩特】若不等t-1≤2~x的解集 \\frac{2x+5}{3}-1\\le2-x 3.【中考·南充】关于x的不等式 2x+a≤1 只有2个 中x的每一个值,都能使关于的不等式3(x-1)+ 5>5x+2(m+x) 3(x-1)+ 成立,则m的取值范围是 () 3x<5x+6, 正整数解,则α的取值范围为 15.【中考·遂宁】解不等式组 且 \\left\\{\\begin{array}{l}3x<5x+6,\\\\\\frac{x+1}{6}\\ge\\frac{x-1}{2},\\end{array}\\right. 1把它 A.-5<a<-3 B.-5≤a<-3 A.m>-\\frac{3}{5} B.m<-\\frac{1}{5} C.-5<a≤-3 D.-5≤a≤-3 集在数轴上表示 写出其整数解. 4.【中考·株洲】下列不等式中与不等式 5x>8+2x 组 C.m<-\\frac{3}{5} D.m>-\\frac{1}{5} 成的不等式组的解集为 \\frac{8}{3}<x<5 的是 () 二、填空题 A.x+5<0 B.2x>10 9.【中考·达州】如图所示,点C位于点A.B之间(不 1-2x, C.3x-15<0 D.-x-5>0 与A.B重合),点C表示1-2x,则x的取值范围 ^{∘}, x 是 5.若代数式 \\frac{1}{4}a 的值不大于 \\frac{1}{2}a+1 的值,则。应满足 () (第9题) A.a≥-4 B.a≤-4 C.a>4 4 D.4 4 >3, 6.小丽同学准备用自己节省的零花钱购买一台学生平 10.【中考·温州】不等式组 \\frac{x-2}{2}\\le4 4的解集为 板电脑,她已存有750元,并计划从本月起每个月节 七年级数学·下(HS版) 110 本页答及点拔T45页\n";
        System.out.println("sim=" + sim(str1, str2));
        System.out.println(isLaji("-"));

    }
}

本文链接: https://jianz.xyz/index.php/archives/333/

1 + 9 =
快来做第一个评论的人吧~