Description:
Implement a method to perform basic compression using counts of repeated characters. If the compressed string is not smaller then return the original string.
Code:
class Main {
public static String compress(String in) {
if (in == null) {
throw new IllegalArgumentException("Input string cannot be null");
}
if (in.length() <= 1) {
return in;
}
StringBuffer out = new StringBuffer();
int count = 1;
for (int i = 1; i < in.length(); i++) {
char current = in.charAt(i);
char previous = in.charAt(i - 1);
if (current == previous) {
count++;
}
else {
out.append(previous);
out.append(count);
count = 1;
}
}
out.append(in.charAt(in.length() - 1));
out.append(count);
return out.toString().length() < in.length() ? out.toString() : in;
}
public static void main(String[] args) {
try {
System.out.println("Should not happen: " + compress(null));
} catch (IllegalArgumentException e) {
System.out.println("Got expected exception for null");
}
System.out.println(compress("").equals(""));
System.out.println(compress("a").equals("a"));
System.out.println(compress("ab").equals("ab"));
System.out.println(compress("aa").equals("aa"));
System.out.println(compress("aabcccccaaa").equals("a2b1c5a3"));
System.out.println(compress("aabb").equals("aabb"));
}
}
Question:
The solution was just based on intuition. The last append was by trial and error which I didn't like (I may be more nervous during the real interview). I would like to know if there is any way to avoid such mistakes, possibly using loop invariants?