pranjal sharma
pranjal sharma

Reputation: 43

Program to compress a string

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.

Upvotes: 1

Views: 225

Answers (2)

Eran
Eran

Reputation: 393771

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());
}

Upvotes: 3

David Knipe
David Knipe

Reputation: 3454

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());
}

Upvotes: 1

Related Questions