java.lang.StringIndexOutOfBoundsException: String index out of range: 45

878 Views Asked by At

I'm trying to make a program that takes in a string like: KKKKKKKKKKKKKBCCDDDDDDDDDDDDDDDKKKKKMNUUUGGGGG

And returns something like this: $K13BCC$D15$K5MNUUU$G5

Another example is XYZAAAAAAGGTCCCCCCTTTAAAAAAAAAAAAAAKK

Returns: XYZ*A6GGT*C6TTT*A14KK

But i get this StringIndexOutOfBoundsException when i try the first input, can anyone tell me why? Here's my code:

import java.util.Scanner;

class RunLengthEncoding {
    public static void main(String[] args) {
        Scanner h = new Scanner(System.in);
        String s;
        char g;
        System.out.print("Enter input string: ");
        s = h.next();

        for (int d = 0; d < s.length(); d++){
            if (!Character.isUpperCase(s.charAt(d))){
                System.out.print("Bad input.");
                return;
            }
        }

        System.out.print("Enter flag character: ");
        g = h.next().charAt(0);

        if (g != '#' && g != '$' && g != '&' && g != '*'){
            System.out.println("Bad input.");
            return;
        }

        char c = s.charAt(0);
        String encode = "";

        for (int n = 0; n < s.length() - 1; n++){
            int k = 0;
            int j = 0;

            while (k + n < s.length() && s.charAt(k + n) == c){
                j++;
                k++;
            }

            if (j > 3){
                encode += g;
                encode += c;
                encode += j;
                n += j - 1;
            }

            else {
                encode += c;
            }
            c = s.charAt(n + 1);
        }
        System.out.println("Encoded: " + encode);
    }
}
2

There are 2 best solutions below

0
Gaetano Rispoli On

The reason that you are getting an out of bounds exception is because you are incrementing n outside of the for loop statement. You do this when you are doing n += j - 1;. This gives you an out of bounds exception because when you do c = s.charAt(n + 1);, n could be greater than or equal to the length of the string. As a general rule, you should not alter the value of the iteration variable in the for loop anywhere outside of the for loop. It makes the code harder to debug.

0
Fire assassin On

For anyone interested in the solution I made:

import java.util.Scanner;

public class RunLengthEncoding {
    public static void main(String[] args){
        Scanner h = new Scanner(System.in);
        String s;
        char g;
        StringBuilder encode = new StringBuilder();

        System.out.print("Enter input string: ");
        s = h.next();

        for (int d = 0; d < s.length(); d++) {
            if (!Character.isUpperCase(s.charAt(d))) {
                System.out.print("Bad input.");
                return;
            }
        }

        System.out.print("Enter flag character: ");
        g = h.next().charAt(0);

        if (g != '#' && g != '$' && g != '&' && g != '*') {
            System.out.println("Bad input.");
            return;
        }

        for (int n = 0; n < s.length(); n++) {
            int k = 1;

            while (n < s.length() - 1 && s.charAt(n) == s.charAt(n + 1)) {
                k++;
                n++;
            }
            if (k > 3) {
                encode.append(g).append(s.charAt(n)).append(k);
            }

            else {
                for (int c = 0; c < k; c++) {
                    encode.append(s.charAt(n));
                }
            }
        }
        System.out.print("Encoded: " + encode);
    }
}