StringUtils源码理解(下)

本文介绍StringUtils的剩下的两个方法

1.计算两个字符串相似度

1.1实现简单介绍

实现原理可参考计算字符串相似度算法——Levenshtein

这里的算法区别在于:存差异值的数组由上文中的二维数组,变成这个实现的两个一维数组,并通过不断的交换数值来实现。

1.2源码理解

//计算两个字符串的差异值
public static int getLevenshteinDistance(CharSequence s, CharSequence t) {
        if (s == null || t == null) {
           //容错,抛出的这个异常是表明在传参的时候,传递了一个不合法或不正确的参数。 好像都这样用,illegal:非法。Argument:参数,证据。
           throw new IllegalArgumentException("Strings must not be null");
        }
        //计算传入的两个字符串长度
        int n = s.length(); 
        int m = t.length(); 
        //容错,直接返回结果。这个处理不错
        if (n == 0) {
            return m;
        } else if (m == 0) {
            return n;
        }
        //这一步是根据字符串长短处理,处理后t为长字符串,s为短字符串,方便后面处理
        if (n > m) {
            CharSequence tmp = s;
            s = t;
            t = tmp;
            n = m;
            m = t.length();
        }

        //开辟一个字符数组,这个n是短字符串的长度
        int p[] = new int[n + 1]; 
        int d[] = new int[n + 1]; 
        //用于交换p和d的数组
        int _d[];

        int i; 
        int j; 
        char t_j; 
        int cost; 
        //赋初值
        for (i = 0; i <= n; i++) {
            p[i] = i;
        }

        for (j = 1; j <= m; j++) {
            //t是字符串长的那个字符
            t_j = t.charAt(j - 1);
            d[0] = j;

            for (i = 1; i <= n; i++) {
                //计算两个字符是否一样,一样返回0。
                cost = s.charAt(i - 1) == t_j ? 0 : 1;
                //可以将d的字符数组全部赋值。
                d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
            }

            //交换p和d
            _d = p;
            p = d;
            d = _d;
        }
        
        //最后的一个值即为差异值
        return p[n];
}

差异值算出来后,除以字符串长度就能算出相似度。

2.去掉字符串中的口音(就是将Ë 转换成 E)

 public static String stripAccents(String input) {}

在这个方法的注释里面,写到java1.6 用到的是java.text.Normalizer,java1.3-1.5用的是sun.text.Normalizer。

同时建议让我们去参考Lucene2.9  的ASCIIFoldingFilter。

2.1带口音的字符从哪里来

首先ASCII码是八位,但是只用到0-127,最高位是用于校验,128-255被用到这样‘Î’,’ Ë‘ 的字符,未收录ASCII中。所以这个方法是将这些带有口音的字符变成标准的(a-z)|(A-Z)。

举例:前面是ascII编码,后面是字符

226:â
227:ã
228:ä
229:å
230:æ
231:ç
232:è
233:é
234:ê

2.2源码理解

这个源码对我来说不容易看,对字符编码之间的转换不理解,看源码会有点吃力,费很多时间,所以就不看了,实现的话,大概就是先把需要转换的部分转换成标准编码,再删除多余的字符。java的字符编码是UTF-8,所以应该变为UTF-8。

3.结束

StringUtils看完了,这两个方法查了不少东西才看下来,同时也学了很多。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值