import java.util.Optional;
/**
* Author:SunLala
* Date: 2022/3/22
* 功能描述:(给定一个字符串 str,返回str的统计字符串。例如,“aaabbadddffc"的统计字符串为"a_3_b_2_a_1_d_3_f_2_c_1)
*/
public class Test7 {
public static String getStatisticStr(String str){
if(!Optional.ofNullable(str).isPresent()){ //如果字符串是空字符串,直接返回空串
return "";
}
char[] chars = str.toCharArray();
StringBuffer sb = new StringBuffer(); //这里用stringBuffer是因为节省内存
int count = 1; //只要某字符遍历到,它的默认统计数就是1,所以这里记为1
for (int i = 0; i < chars.length; i++) { //遍历数组
if(i == 0){ //第一位直接拼接
sb.append(chars[i]);
}else{ //非第一位的处理
if(chars[i] == chars[i-1]){ //如果和前一位相同则count+1
count += 1;
}else{ //如果和前一位不相同,则拼接count+和当前字符
sb.append("_"+count +"_"+chars[i]);
count = 1;
}
}
}
sb.append("_"+count); //拼接最后一个字符的数目
return sb.toString();
}
/**
* 参考书上的进行优化
* @param str
* @return
*/
public static String getStatisticStr2(String str) {
if(!Optional.ofNullable(str).isPresent()){
return "";
}
char[] chars = str.toCharArray();
StringBuffer sb = new StringBuffer(String.valueOf(chars[0])); //注意这里不能这么写new StringBuffer(chars[0]), StringBuffer的这个构造函数参数相当于是用了int值,而不是字符串
int count = 1;
for (int i = 1; i < chars.length; i++) {
if (chars[i] == chars[i - 1]) {
count += 1;
} else {
// sb.append("_" + count + "_" + chars[i]);
sb = contact(sb,String.valueOf(count),String.valueOf(chars[i])); //觉得这里没必要,不过如果调用contact的地方多了可以把它提成一个方法
count = 1;
}
}
return sb.toString();
}
public static StringBuffer contact(StringBuffer res, String count, String cur){
return res.append("_"+count + "_" + cur);
}
public static void main(String[] args) {
System.out.println(getStatisticStr2("aaabbadddffc"));
System.out.println(getStatisticStr2("aaasaabffeeqqbadddffcccc"));
System.out.println(getStatisticStr2("11afsdfaasaab33f22f"));
}
}
总结:
今天很棒,自己完整的把算法写出来了,虽然有些小瑕疵,但是基本可以忽略
1. 第一个字符的拼接放在了循环里,没有必要,可以直接放在循环外面拼接
2.自己使用的StringBuffer,比书上用的String在数据量大的情况下,效果更好
3. 拼接方法可以提炼出来
4. new StringBuffer(String.valueOf(chars[0])) 刚开始的时候参数传了一个char数组的第一个字符,构造函数将字符的ASSIC码当int用了,导致效果半天出不来,折腾了一小会才发现这个问题。如果想初始化一个带字符串的StringBuffer,记得传字符串在构造函数里面