zoukankan      html  css  js  c++  java
  • 字符串相似度计算----编辑距离

    题目描述:

    要求两字符串有差异的字符个数。例如: 
    aaaaabaaaaa 
    aaaaacaabaa 
    这两个字符串,最大公共字串长度是5,但它们只有两个字符不同,函数输出值应为2。 
    如果是: 
    aaabbbcccddd 
    aaaeeeddd 
    函数的输出值应该是6。 

    比较形象地形容一下,把两个字符串排成上下两行,每个字符串都可以在任何位置插入空格以便上下对齐,每个列上至少有一个字符来自这两个字符串。当对齐程度最高的时候,没有对上的列的数即为函数输出值。 
    aaabbbcccddd 
    aaaeeeddd 
    最优对齐状态是: 
    aaabbbcccddd 
    aaaeee     ddd 
    没有对上的列是6,函数输出值为6。 
    如果是: 
    abcde 
    acefg 
    最优对齐状态是: 
    abcde 
    a  c  efg 
    没有对上的列数是4,函数输出值为4。

    问题抽象归类:(编辑距离问题)

    设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括:

    (1)删除一个字符;
    (2)插入一个字符;
    (3)将一个字符改为另一个字符。
    将字符串A变换为字符串B所用的最少字符操作数称为字符串A到B的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。
    要求:
    输入:第1行是字符串A,第2行是字符串B。
    输出:字符串A和B的编辑距离d(A,B)

    思路:动态规划

    开一个二维数组d[i][j]来记录a0-ai与b0-bj之间的编辑距离,要递推时,需要考虑对其中一个字符串的删除操作、插入操作和替换操作分别花费的开销,从中找出一个最小的开销即为所求

    具体算法:

    首先给定第一行和第一列,然后,每个值d[i,j]这样计算:d[i][j]   =   min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+(s1[i]  ==  s2[j]?0:1));   
     最后一行,最后一列的那个值就是最小编辑距离 

    package com.kunlun.bd.util;
    
    /** 
     * java 两字符串相似度计算算法  Levenshtein Distance编辑距离算法      
    * 
     * @author jianpo.mo 
     */ 
    public class Similarity { 
    
        private static int min(int one, int two, int three) { 
            int min = one; 
            if(two < min) { 
                min = two; 
            } 
            if(three < min) { 
                min = three; 
            } 
            return min; 
        } 
        
        public static int ld(String str1, String str2) { 
            int d[][];    //矩阵 
            int n = str1.length(); 
            int m = str2.length(); 
            int i;    //遍历str1的 
            int j;    //遍历str2的 
            char ch1;    //str1的 
            char ch2;    //str2的 
            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++) {    //遍历str1 
                ch1 = str1.charAt(i-1); 
                //去匹配str2 
                for(j=1; j<=m; j++) { 
                    ch2 = str2.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]; 
        } 
        
        public static double sim(String str1, String str2) { 
            int ld = ld(str1, str2); 
            return 1 - (double) ld / Math.max(str1.length(), str2.length()); 
        } 
        
        public static void main(String[] args) { 
           
            String str1="江苏-南通~江苏-泰州~在外面外面浴室过夜,昨晚包夜跟人打架被赶出来,没地方去就到浴室睡觉了!你今天什么时候考试啊?      ";
    
            String str2="在外面外面浴室过夜,昨晚包夜跟人打架被赶出来,没地方去就到浴室睡觉了!你今天什么时候考试啊?";
    
            System.out.println("ld="+ld(str1, str2)); 
            System.out.println("sim="+sim(str1, str2)); 
        } 
    } 
  • 相关阅读:
    【JAVA笔记——道】JAVA对象销毁
    【JAVA笔记——道】并发编程CAS算法
    httpClientUtil的get请求
    python基础 day11 下 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业
    python基础 day11 上 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 事务 索引 python 操作mysql ORM sqlachemy学习
    Python基础 Day10 Gevent协程 SelectPollEpoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 RedisMemcached缓存 Paramiko SSH Twsited网络框架
    python基础 day9 进程、与线程区别 python GIL全局解释器锁 线程 进程
    python基础 day8 Socket语法及相关 SocketServer实现多并发
    python基础 day7 面向对象高级语法部分 异常处理 异常处理 Socket开发基础
    python基础 day6 面向对象的特性:封装、继承、多态 类、方法、
  • 原文地址:https://www.cnblogs.com/bendantuohai/p/4650454.html
Copyright © 2011-2022 走看看