本文介绍StringUtils的剩下的两个方法
实现原理可参考计算字符串相似度算法——Levenshtein
这里的算法区别在于:存差异值的数组由上文中的二维数组,变成这个实现的两个一维数组,并通过不断的交换数值来实现。
//计算两个字符串的差异值 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]; }
差异值算出来后,除以字符串长度就能算出相似度。
public static String stripAccents(String input) {}
在这个方法的注释里面,写到java1.6 用到的是java.text.Normalizer,java1.3-1.5用的是sun.text.Normalizer。
同时建议让我们去参考Lucene2.9? 的ASCIIFoldingFilter。
首先ASCII码是八位,但是只用到0-127,最高位是用于校验,128-255被用到这样‘?’,’ ?‘ 的字符,未收录ASCII中。所以这个方法是将这些带有口音的字符变成标准的(a-z)|(A-Z)。
举例:前面是ascII编码,后面是字符
226:a
227:?
228:?
229:?
230:?
231:?
232:è
233:é
234:ê
这个源码对我来说不容易看,对字符编码之间的转换不理解,看源码会有点吃力,费很多时间,所以就不看了,实现的话,大概就是先把需要转换的部分转换成标准编码,再删除多余的字符。java的字符编码是UTF-8,所以应该变为UTF-8。
StringUtils看完了,这两个方法查了不少东西才看下来,同时也学了很多。
?
?
?
?