第一种,只统计字符出现次数,比如aabcccccaaa,压缩成a5b1c5
思路:利用hashMap键的唯一性
public static String doDepressTwo(String str) { if ("".equals(str)) return str; char[] chars = str.toCharArray(); HashMap<Character, Integer> map = new HashMap<>(); for (char c : chars) { if (map.containsKey(c)) { //如果存在该键,则只需要value+1 Integer integer = map.get(c); map.put(c, ++integer); } else { //如果不存在该键,就直接放入,value为1 map.put(c, 1); } } StringBuilder sb = new StringBuilder(); map.entrySet().forEach(entry -> { //将key和value拼接到sb sb.append(entry.getKey()).append(entry.getValue()); }); return sb.toString(); }
第二种,统计相邻字符串出现次数,比如aabcccccaaa,压缩成a2b1c5a3
思路:需要维护一个当前对比字符,一个字符出现次数,用第n个字符去和第n+1个字符对比,相等则出现次数+1,不相等则拼接在字符串后面
public static String doDepress(String str) { //字符串为空直接返回 if ("".equals(str)) return str; StringBuilder buffer = new StringBuilder(); //用第n个字符去和第n+1个字符对比 char c = str.charAt(0); //记录字符出现次数,默认为1 int repeat = 1; for (int i = 1; i < str.length(); i++) { if (c == str.charAt(i)) { //如果第n个字符和第n+1个字符相等,则出现次数+1 repeat++; } else { //如果第n个字符和第n+1个字符不相等,则拼接在字符串后面 buffer.append(c).append(repeat); //拼接完后重置当前字符串 c = str.charAt(i); //重置字符出现次数 repeat = 1; } } //最后一组在for循环里是没有拼接的 return buffer.append(c).append(repeat).toString(); }
测试:
public static void main(String[] args) { log.info("唱跳rap的蔡徐鸡========>{}", doDepress("唱跳rap的蔡徐鸡")); log.info("唱跳raaaaap的的蔡徐鸡==>{}", doDepress("唱跳raaaaap的的蔡徐鸡")); log.info("aabcccccaaa=========>{}", doDepress("aabcccccaaa")); log.info("唱跳rap的蔡徐鸡========>{}", doDepressTwo("唱跳rap的蔡徐鸡")); log.info("唱跳raaaaap的的蔡徐鸡==>{}", doDepressTwo("唱跳raaaaap的的蔡徐鸡")); log.info("aabcccccaaa=========>{}", doDepressTwo("aabcccccaaa")); }
结果:
唱跳rap的蔡徐鸡========>唱1跳1r1a1p1的1蔡1徐1鸡1
唱跳raaaaap的的蔡徐鸡==>唱1跳1r1a5p1的2蔡1徐1鸡1
aabcccccaaa=========>a2b1c5a3
唱跳rap的蔡徐鸡========>p1徐1唱1a1蔡1鸡1r1跳1的1
唱跳raaaaap的的蔡徐鸡==>p1徐1唱1a5蔡1鸡1r1跳1的2
aabcccccaaa=========>a5b1c5