我是靠谱客的博主 受伤短靴,最近开发中收集的这篇文章主要介绍不同长度的字符串/中文串相似度对比算法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.背景介绍

今天在公司接到一个需求,大概是这样的.我们ERP系统数据库有张customer(客户)表,其中有个字段是小区名称(plotName),当初在录入数据时没有对这一字段做界定和规范,由人工手动录入,这就导致两位客户本是一个小区,而录入的小区名可能不是完全一样的结果.例如张三和李四都住在武林邸,而张三录入的数据是"武林邸",李四录入的数据的"杭州市西湖区武林邸",又或是舞林邸等.由于业务需要,现需要对这些小区名进行名称规整,如上述例子都规整为"杭州市西湖区武林邸".

2.解决方案如下

既然要规整,就要有统一的名称规范,最终决定从安居客,租房网等爬出杭州市各小区的标准名称.再用数据库现有数据与之对比.列出最相似的前三个名称,然后泽其一修数据库数据.

如下图所示:匹配度及为相似度算法计算所得结果.

3.难点

难点就是字符串相似度对比算法的设计,网上查阅大量资料,如字符串最小编辑距离匹配算法此处不适用,因为对比的字符串与目标字符串长度不一样,会导致对比结果不是正确的.用代码和数据验证如下:

对比的三个字符串如下:                                     目标字符串为:"龙悦湾金石院子"

  1. "浙江省杭州市拱墅区龙悦湾金石院子"
  2. "金石院子十六幢二单元302"
  3. "金子"
 public static void main(String[] args){
        LinkedList list=new LinkedList();
        String source = "龙悦湾金石院子";//目标字符串
        String target1 = "浙江省杭州市拱墅区龙悦湾金石院子";
        String target2="金石院子十六幢二单元302";
        String target3="金子";
        System.out.println(target1+"最小编辑距离是:"+minEdit_distance(source,target1));
        System.out.println(target2+"最小编辑距离是:"+minEdit_distance(source,target2));
        System.out.println(target3+"最小编辑距离是:"+minEdit_distance(source,target3));
    }

其中minEdit_distance()方法是最小编辑距离算法,根据此算法的思想,如果最小编辑距离值越小,则说明两个字符串越相似.而此处打印结果为9,12,5.即"金子"与"龙悦湾金石院子"最相似,"浙江省杭州市拱墅区龙悦湾金石院子"第二,"金石院子十六幢二单元302"第三,而实际应该是"金子"与"龙悦湾金石院子"最不相似,是不期望得到的结果.

打印结果:

 

4.最终解决方案

将字符串和目标字符串去空格后转为单字符集,定义一个变量intersection,自定义算法计算让intersection值增加,相似度百分比值=intersection*2/unionLength(两个字符串长度和)*100.

代码如下:

 public static String compareStrings(String str1, String str2) {
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数
        ArrayList pairs1 = wordLetterPairs(str1.toUpperCase());
        ArrayList pairs2 = wordLetterPairs(str2.toUpperCase());
        int intersection = 0;
        int union = pairs1.size() + pairs2.size();
        for (int i=0; i<pairs1.size(); i++) {
            Object pair1=pairs1.get(i);
            for(int j=0; j<pairs2.size(); j++) {
                Object pair2=pairs2.get(j);
                if (pair1.equals(pair2)) {
                    intersection++;
                    pairs2.remove(j);
                    break;
                }
            }
        }
        return df.format((2.0*intersection)/union*100)+"%";
    }
private static String[] letterPairs(String str) {
        int numPairs = str.length()-1;
        String[] pairs = new String[numPairs];
        for (int i=0; i<numPairs; i++) {
            pairs[i] = str.substring(i,i+2);
        }
        return pairs;
    }

    private static ArrayList wordLetterPairs(String str) {
        ArrayList allPairs = new ArrayList();
        String[] words = str.split("\s");
        for (int w=0; w < words.length; w++) {
            String[] pairsInWord = letterPairs(words[w]);
            for (int p=0; p < pairsInWord.length; p++) {
                allPairs.add(pairsInWord[p]);
            }
        }
        return allPairs;
    }

运行结果:正确

 

 

最后

以上就是受伤短靴为你收集整理的不同长度的字符串/中文串相似度对比算法的全部内容,希望文章能够帮你解决不同长度的字符串/中文串相似度对比算法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(197)

评论列表共有 0 条评论

立即
投稿
返回
顶部