1

I'm writing a program that compresses strings using run-length encoding.

E.g. for input "aaabbccccddd", output should be "a3b2c4d3".

Currently the program shows no output.

public static void main(String[] args) {
    String words1 = "aabbbcccc";
    String words2 = compress(words1);
    System.out.println(words2);
  }

private static String compress(String w1) {
    StringBuilder w2 = new StringBuilder();
    int k = 0;
    for (int i = 0; i < w1.length(); ) {
        k++;
        if(i+1>w1.length() || w1.charAt(i) != w1.charAt(i+1)) {
          w2.append(w1.charAt(i));
          w2.append(k);
          k = 0;
        }
    }
    return ((w2.length() > w1.length())? w1: w2.toString());
}

Output shows nothing in IntelliJ and I can't figure out why!! Also tried without StringBuilder. Even tried without StringBuilder and changing the return type to void in case it was a problem with handling a String. Same, no result.

1
  • 1
    Learn how to use the debugger of your IDE. You can view the inner workings of the program and find out where it goes wrong. Commented Jun 25, 2017 at 6:58

2 Answers 2

3

One thing you forgot is i++ in your for loop. This causes an infinite loop.

Besides that, you have an issue with the condition of your loop. It should be i<w1.length()-1 to avoid IndexOutOfBoundsException caused by w1.charAt(i+1).

Once you change that, you'll see that the last character of the String is not handled. You can handle it outside the loop.

private static String compress(String w1) {
  StringBuilder w2 = new StringBuilder();
  int k =0;
  for (int i=0; i < w1.length()-1; i++) {
    k++;
    if (w1.charAt(i) != w1.charAt(i+1)) {
      w2.append(w1.charAt(i));
      w2.append(k);
      k=0;
    }
  }

  w2.append (w1.charAt (w1.length ()-1));
  w2.append (k+1);

  return ((w2.length() > w1.length())? w1: w2.toString());
}

This outputs

a3b2c4d3

for the input

aaabbccccddd

EDIT:

As David commented correctly, you do have code to handle the last character within the loop. You just had a wrong range check in the if statement.

The following fixes all the issues, without the need to handle the last character separately:

private static String compress(String w1) {
  StringBuilder w2 = new StringBuilder();
  int k =0;
  for (int i=0; i < w1.length(); i++) {
    k++;
    if (i+1 >= w1.length() || w1.charAt(i) != w1.charAt(i+1)) {
      w2.append(w1.charAt(i));
      w2.append(k);
      k=0;
    }
  }

  return ((w2.length() > w1.length())? w1: w2.toString());
}
Sign up to request clarification or add additional context in comments.

1 Comment

I don't think you fully understand OP's code. The last character was supposed to be handled inside the loop by the i+1>w1.length() part (which you've forgotten to delete as it's not needed in your solution). The problem is that it should be i+1>=w1.length(). This should prevent the IndexOutOfBoundsException.
1

As Eran said, you forgot the i++ part. Also, i+1>w1.length() should be i+1>=w1.length(). It should work with those two changes.

private static String compress(String w1) {
    StringBuilder w2 = new StringBuilder();
    int k = 0;
    for (int i = 0; i < w1.length(); i++) {
        k++;
        if(i+1>=w1.length() || w1.charAt(i) != w1.charAt(i+1)) {
          w2.append(w1.charAt(i));
          w2.append(k);
          k = 0;
        }
    }
    return ((w2.length() > w1.length())? w1: w2.toString());
}

1 Comment

Thank you. I don't know how I missed out the incrementation and caused the crazy mess I was in!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.