题目:
注:该题目的要求是“压缩连续相同字符”,因此不能用HashMap或LinkedHashMap来求解,因为二者统计的是整个字符串中字符的总出现次数(而非“连续段”的次数)。例:
输入是“ABAB”,代码会统计“A:2 B:2”,则输出为“A2B2”,而本应输出为“ABAB”。导致有一个测试用例不通过。
解一:获取字符串并创立一个可变字符数组,从下标为0开始遍历字符串,设置一个计数器count为0;再设置一个子for循坏j,初始j=i(将i赋为j是因为count初始为0),判断下标为i的字符于下标为j的字符是否相等,相等的话count++;否则退出子循坏。if语句判断当前count是否大于一,进行相应的字符数组进行追加。在上面子循坏中如果i对应的字符与j对应的字符不相等的话,此时j下标对应的元素是新的不同于前面的字符(例“AAABB”,此时j指向第一个B的下标),i = j-1是,i指向最后一个A,再外层循坏i++,此时i指向第一个B,开始新一轮的判断。最后判断字符数组长度与字符串的长度,进行相应的输出。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String str=scan.next(); StringBuilder sb=new StringBuilder(); for(int i=0;i<str.length();i++){ int count=0; int j=i; for(;j<str.length();j++){ if(str.charAt(i)==str.charAt(j)){ count++; } else break; } if(count>1){ sb.append(str.charAt(i)); sb.append(count); i=j-1; } else{ sb.append(str.charAt(i)); } } if(sb.length()<str.length()){ System.out.print(sb.toString()); } else{ System.out.print("NO"); } scan.close(); } }解二:用正则表达式解该题。Pattern.compile("([a-zA-Z])\\1*")作用是编译一个正则表达式规则,生成Pattern对象。在([a-zA-Z])中()是捕获组,会把匹配到的内容暂存(这里暂存单个字母,范围是a-z或A-Z),[a-zA-Z]表示匹配任意一个字母(大小写均可)。\\1*中\\1是反向引用,指代前面捕获组匹配到的字符。*表示匹配0次或多次,整体含义:匹配与前面捕获组相同的字符,连续出现任意次。m.find()的作用是在字符串中查找下一个符合正则规则的子串。m.group(0).charAt(0)表示获取当前匹配子串的第一个字符(比如子串是“AAA”,则取“A”);m.group(0).length(0)表示获取当前匹配子串的长度(比如子串是“AAA”,则长度为3)。
获取字符串,创建正则表达式匹配器对象,范围为a-z或A-Z。while循坏持续执行,直到遍历完字符串中所有符合条件的连续字符段,再判断其子串长度是否大于一,对可变字符数组进行相应的追加,最后赋给字符串s2进行判断最后的输出。
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String s=scan.next(); String s2; Pattern p=Pattern.compile("([a-zA-Z])\\1*"); Matcher m= p.matcher(s); StringBuilder stringBuilder=new StringBuilder(); while (m.find()) { if(m.group(0).length()>1) stringBuilder.append(""+m.group(0).charAt(0)+m.group(0).length()); else stringBuilder.append(""+m.group(0).charAt(0)); } s2=stringBuilder.toString(); if (s2.length()==s.length()) System.out.println("NO"); else System.out.println(s2); scan.close(); } }解三:获取字符串同时将其变为字符数组。设置布尔型flag记录是否可以压缩。for循坏遍历数组,首先记录出现次数为一,先不判断是否重复出现,先将字符追加到可变数组中,while循坏判断过程中是否有相同字母出现,有的话次数加一,下标向后移一位。判断次数是否大于1,大于的话追加,布尔型赋为true。最后如果false为true的话说明有重复出现的输出,否则为no。
注:该方法没有判断最后长度是否有所减少,个人感觉有点失误。例:输入AABBC,压缩后为A2B2C,其长度仍为5,应输出no。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); char[] cs = scanner.next().toCharArray(); StringBuilder sb = new StringBuilder(); boolean flag = false; //记录是否可以压缩 for (int i = 0; i < cs.length; i++) { int cnt = 1; //字母出现次数 if (cnt == 1) sb.append(cs[i]); //循环直到后一位字母不一样为止。过程中如果有相同字母出现,则次数加1。 while (i < cs.length - 1 && cs[i] == cs[i + 1]) { cnt++; i++; } //字母出现多次,可以压缩 if (cnt != 1) { sb.append(cnt); flag = true; } } System.out.println(flag ? sb.toString() : "NO"); } }解四:获取字符串并转成字符数组,用LinkedHashSet存储字符(去重且保留顺序),用于后续判断字符是否重复。第一个判断:如果字符串中没有重复字符(无法压缩),直接输出NO并结束。第二个判断:是否连续。第三个判断:压缩字符,输出字符与其对应的次数。
import java.util.LinkedHashSet; import java.util.Scanner; import java.util.Set; public class text { public static void main(String[] args) { Scanner scan = new Scanner(System.in); String strs = scan.next(); char[] arrs = strs.toCharArray(); int num =0; Set<Character> set = new LinkedHashSet<>(); for (char c : strs.toCharArray()) { set.add(c); } if(set.size()==arrs.length) {//判断是否节省空间 System.out.println("NO"); return; } for (int i = 0; i < arrs.length-1; i++) {//判断是否连续 if(arrs[i]>arrs[i+1]) { System.out.println("NO"); return; } } for (int i = 0; i <= arrs.length-1; i++) {//压缩字符 num++; if(i==arrs.length-1) { System.out.print(arrs[i]); System.out.print(num); break; } if(arrs[i]!=arrs[i+1]) { System.out.print(arrs[i]); System.out.print(num); num = 0; } } } }解五:获取字符串,创建一个新的可变字符数组,将字符串0号下标的字符赋给当前字符,设置计数器初始为1,从1号下标开始遍历,如果有重复元素出现count++,进行相应的追加,最后判断长度进行输出。
import java.util.*; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //在此输入您的代码... Scanner scanner = new Scanner(System.in); String x = scanner.next();//获取字符串 StringBuilder str = new StringBuilder();//创建一个新的可变字符数组 char currenta = x.charAt(0);//将字符串0号下标的字符赋给当前字符 int count = 1;//设置计数器初始为1 for (int i = 1;i<x.length();i++){//从下标为1开始 if (x.charAt(i) == currenta){//如果有重复元素出现count++ count++; }else { str.append(currenta);//将当前字符追加到str中 if (count>1){//判断次数是否大于1 str.append(count); } currenta = x.charAt(i);//再将新的字符赋给当前字符,进行判断 count = 1; } } str.append(currenta); if (count>1){ str.append(count); } if (str.length()<x.length()){//判断是否长度小于,小于的话输出,否则为no System.out.println(str); }else { System.out.println("NO"); } scan.close(); } }