You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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);
            }
        }
    }
}

代码关键点解释

  1. 初始化逻辑:先把字符串第一个字符设为currentChar,计数从1开始(因为已经有一个字符了)
  2. 遍历判断:从索引1开始遍历,每次和currentChar比较,相同就累加计数,不同就输出之前的结果并切换字符
  3. 收尾处理:循环结束后,最后一组字符还没处理,必须单独输出,否则会漏掉最后一段
  4. 方法封装:把判断计数和输出的逻辑抽成单独方法,主代码更清晰易读,也方便后续修改规则

关于教授提到的“不用循环”的实现

如果想用更简洁的方式(不用显式遍历循环),可以用正则表达式匹配连续重复的字符组,代码会更短:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:21:05