今天在看Druid的源码时, 无意间看到StringUtil
里面的subString方法还挺有趣的 想到可以在算法比赛的时候模仿写着这方法
先上代码:
/**
* Example: subString("abcdc","a","c",true)="bcd"
* 第四个参数表示是否到最后的一个c 这例子中 若为false则 结果为 b
* @param src
* @param start null while start from index=0
* @param to null while to index=src.length
* @param toLast true while to index=src.lastIndexOf(to)
* @return
*/
public static String subString(String src, String start, String to, boolean toLast) {
if(!toLast) {
return subString(src, start, to);
}
int indexFrom = start == null ? 0 : src.indexOf(start);
int indexTo = to == null ? src.length() : src.lastIndexOf(to);
if (indexFrom < 0 || indexTo < 0 || indexFrom > indexTo) {
return null;
}
if (null != start) {
indexFrom += start.length();
}
return src.substring(indexFrom, indexTo);
}
正如示例
Example: subString(“abcdc”,“a”,“c”,true)="bcd"
第四个参数表示是否到最后的一个c 这例子中 若为false则 结果为 b
那么
Example: subString(“abcdc”,“ab”,“c”,true)="cd"
那么
Example: subString(“abcdc”,“bc”,“c”,true)="d"
算法显而易见 首先判断是否第四个参数为false(false表示不到最后一个“to”)
若此参数为false则跳转下面重载的方法2
然后再给indexFrom indexTo分别赋值 这个好理解
在下面 判断 null != start 若成立 则让 indexFrom变为加上start的长度的位置
意思即为 :除去"start"位置及之前的字母
若不加上这个判断 则只会从"start"开始取subString 并且包含start的字母
比如 StringUtils.subString(“abcdc”,“b”,“c”,true)="bcd"
只会从b开始并且包含b
StringUtils.subString(“dbcdc”,“db”,“c”,true)=“dbcd”
只会从db开始并且包含db
此外:
发现仍有一个问题即 若给定的start和to相同 并且 字符串的开头结尾也相同 并且将第四个参数改为false 则找不到
如 StringUtils.subString(“efcfee”, “e”, “e”, false);
会报java.lang.StringIndexOutOfBoundsException: begin 1, end 0, length 6
思考发现,
因为开始结束都一样 并且不说明“to”的e是最后一个 那么他会以为“to”是第一个e即end=0 , start=1(end=0 , start=1是因为 上面说的indexFrom += start.length();)
附:重载的方法2
/**
* Example: subString("abcd","a","c")="b"
*
* @param src
* @param start null while start from index=0
* @param to null while to index=src.length
* @return
*/
public static String subString(String src, String start, String to) {
int indexFrom = start == null ? 0 : src.indexOf(start);
int indexTo = to == null ? src.length() : src.indexOf(to);
if (indexFrom < 0 || indexTo < 0 || indexFrom > indexTo) {
return null;
}
if (null != start) {
indexFrom += start.length();
}
return src.substring(indexFrom, indexTo);
}