如何用Java的charAt()实现游程编码?求助解决字符比较问题
解决Java游程编码中的相邻字符比较问题
嘿,我来帮你搞定这个游程编码的作业问题!先帮你梳理下现有代码里的核心问题,再给你一个清晰的循环实现方案。
你的代码里的核心问题
首先看外层循环的条件:s1.charAt(counter) <= s1.length()-1,这是把字符的ASCII值和字符串长度的数值做比较,完全逻辑错误,应该是判断counter < s1.length()才对。
然后内层循环的问题更大:s1.charAt(counter) == s1.charAt(j)+1这个条件完全不是在判断相邻字符是否相同,而且j从0开始,还在循环里修改外层的counter,很容易导致数组越界或者无限循环——这就是你现在代码跑不起来的核心原因。
正确的循环实现思路
其实游程编码用单循环就能搞定,核心逻辑很简单:
- 记录当前正在统计的字符
- 记录该字符连续出现的次数
- 遍历字符串时,每遇到和当前字符相同的就累加计数;遇到不同的,就先处理之前的统计结果,再切换当前字符并重置计数
- 遍历结束后,别忘了处理最后一组字符(因为循环到最后时,最后一组还没输出)
完整实现代码
import java.util.Scanner; public class RunLengthEncoding { public static void main(String[] args) { Scanner reader = new Scanner(System.in); System.out.print("Enter a string: "); String s1 = reader.nextLine(); reader.close(); if (s1.isEmpty()) { System.out.println("Empty string, nothing to encode."); return; } System.out.println("Run length encoded version of string: "); char currentChar = s1.charAt(0); int count = 1; // 从第二个字符开始遍历 for (int i = 1; i < s1.length(); i++) { char nextChar = s1.charAt(i); if (nextChar == currentChar) { count++; } else { // 输出当前统计的字符组 printEncodedChar(currentChar, count); // 切换到新字符,重置计数 currentChar = nextChar; count = 1; } } // 处理最后一组字符 printEncodedChar(currentChar, count); } // 把编码输出逻辑封装成方法,让主代码更简洁 private static void printEncodedChar(char c, int count) { char ast = '*'; if (count >= 4) { System.out.print(ast + String.valueOf(c) + count); } else { // 次数不足4次时,直接重复输出对应次数的字符 for (int i = 0; i < count; i++) { System.out.print(c); } } } }
代码关键点解释
- 初始化逻辑:先把字符串第一个字符设为
currentChar,计数从1开始(因为已经有一个字符了) - 遍历判断:从索引1开始遍历,每次和
currentChar比较,相同就累加计数,不同就输出之前的结果并切换字符 - 收尾处理:循环结束后,最后一组字符还没处理,必须单独输出,否则会漏掉最后一段
- 方法封装:把判断计数和输出的逻辑抽成单独方法,主代码更清晰易读,也方便后续修改规则
关于教授提到的“不用循环”的实现
如果想用更简洁的方式(不用显式遍历循环),可以用正则表达式匹配连续重复的字符组,代码会更短:
import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RunLengthEncodingRegex { public static void main(String[] args) { Scanner reader = new Scanner(System.in); System.out.print("Enter a string: "); String s1 = reader.nextLine(); reader.close(); if (s1.isEmpty()) { System.out.println("Empty string, nothing to encode."); return; } System.out.println("Run length encoded version of string: "); // 正则匹配连续重复的字符组 Pattern pattern = Pattern.compile("(.)\\1*"); Matcher matcher = pattern.matcher(s1); while (matcher.find()) { char c = matcher.group(1).charAt(0); int count = matcher.group().length(); if (count >= 4) { System.out.print("*" + c + count); } else { System.out.print(matcher.group()); } } } }
这个方法用正则自动识别所有连续重复的字符,代码更简洁,但对于刚学Java的同学来说,循环实现可能更容易理解和调试,也符合你想要的“简洁且易读”的需求。
内容的提问来源于stack exchange,提问作者Declan Sudbury
相关产品推荐
相关产品推荐

