1

I have to find number of consecutive capital letters in a string. For Example, "LITTLE RABBIT" Number of consecutive capital letters = 2 ( first is TT and second is BB) Program is not working.

The program is giving an error message as follows

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

try {
    String s = " LITTLE RABBIT";
    s.toUpperCase();
    int l = s.length();
    int a = 0;
    char ch1, ch2;
    for (int i = 0; i < l; i++) {
        ch1 = s.charAt(i);
        ch2 = s.charAt(i + 1);
        if (ch1 == ch2) {
            a++;
        }
    }
    System.out.println(a);
} catch (StringIndexOutOfBoundsException e) {
    System.out.println(e);
}
Ömer Erden
  • 6,171
  • 5
  • 26
  • 40
  • Firstly, you're not supposed to catch `StringIndexoutOfBoundsException` unless you're just debugging (and even then...). Secondly, the root cause is your loop break variable is set correctly, but you defile it by arbitrarily incrementing it by 1 in the statement: `s.charAt(i+1);` – Mena May 21 '19 at 10:52
  • 1
    use i < l-1 in for-loop – Nitika May 21 '19 at 10:54
  • By the way, `s.toUpperCase();` does nothing useful. – Andy Turner May 21 '19 at 10:56
  • you can also trim the string to remove extra white-spaces. – Nitika May 21 '19 at 10:58
  • I know s.toUpperCase(); does nothing useful. This is a test prog, I still have to modify it. – the_first_Airbender May 21 '19 at 11:04
  • It seems the question was more about finding the number of consecutive letters in a string than the cause of the exception. It's worth noting that the original problem can be solved much more simply with the regular expression: `([A-Z])\1+`. Then it's only a matter of counting the number of matches https://stackoverflow.com/questions/7378451/java-regex-match-count – SDJ Jun 06 '19 at 16:03

4 Answers4

0

The reason you get an exception is rather simple. In the last run of your loop you check if the last char of the string equals the next char. Your String does not have any more characters so you get an exception. To prevent this problem you have to cut your loop and use for (int i=0; i < l-1; i++). Remember: The first char in a String has the index 0 and the last char has index l-1. In this setup you don't have to run the loop with the last char so you can stop before l-1

asuras
  • 93
  • 7
0

try using below code. you hace to traverse from 0 to String Size - 1. But you're traversing at last position where no element is present. that's why you're getting that StringIndexOutOfBounds Exception.

public static void main(String[] args) {
        try {
            String s = " LITTLE RABBIT";
            s.trim().toUpperCase();
            int l = (s.length() - 1);
            int a = 0;
            char ch1, ch2;
            for (int i = 0; i < l; i++) {
                ch1 = s.charAt(i);
                ch2 = s.charAt(i + 1);
                if (ch1 == ch2) {
                    a++;
                }
            }
            System.out.println(a);
        } catch (StringIndexOutOfBoundsException e) {
            e.printStackTrace();
        }

    }
Onkar Musale
  • 859
  • 11
  • 23
0

Firstly, you're not supposed to catch StringIndexoutOfBoundsException unless you're just debugging (and even then...).

Secondly, the root cause is your loop break variable is set correctly, but you defile it by arbitrarily incrementing it by 1 in the statement: s.charAt(i+1);

Thirdly, here's a slightly simpler solution using regex.

static int findMaxConsecutiveCapitalizedLetters(String input) {
    // TODO null/empty check
    // TODO move the statement below to a constant somewhere
    Pattern p = Pattern.compile("(\\p{Upper})\\1+");
    Matcher m = p.matcher(input);
    int counter = 0;
    while (m.find()) {
        if (m.group().length() > counter) {
            counter = m.group().length();
        }
    }
    return counter;
}

Given...

String[] test = {"LITTLE RABBIT", "BIG RAbbIT", "DEMON RABBBIT FROM HELL"};
Arrays.stream(test).forEach(
    (s) -> System.out.println(findMaxConsecutiveCapitalizedLetters(s))
);

You'll get:

2 (because LITTLE and RABBIT have both 2)
0 (no repeated capitalized letters)
3 (RABBBIT has 3 here, HELL only 2 so it returns the biggest)

Note about the pattern:

| sets group 1 for back reference (group 0 is always the whole match if any)
| | posix script for uppercase letters
| |         | back-reference to group 1
| |         |  1 + repetition of back-reference
| |         |  |
(\\p{Upper})\\1+
Mena
  • 46,817
  • 11
  • 84
  • 103
0

Your issue is that you are going through all the string while calling the next character as well. Therefore when reaching the last character you will be met with that exception due to you calling the character after the last one. Since you are looking for a simple solution, here is the fixed code.

try
{
    String s = " LITTLE RABBIT";
    s.toUpperCase();
    int l = s.length();
    int a =0;
    char ch1, ch2;
    //Remove one so you no longer call it. It fixes it since the last one can't be a pair.
    for( int i =0; i < l-1; i++)
    {
        ch1 = s.charAt(i);
        ch2 = s.charAt(i+1);
        if( ch1 == ch2)
        {
            a++;
        }
    }
    System.out.println(a);
}
catch(StringIndexOutOfBoundsException e)
{
    System.out.println(e);
}
masecla22
  • 1
  • 1