LMA
LMA

Reputation: 121

Return each character just after its consecutive occurrences

I want to return each character just after its consecutive occurrences
For example:

Input : GeeeEEKKKss
Output : 1G3e2E3K2s

Input : ccccOddEEE
Output : 4c1O2d3E

I have developed this piece of code and it works fine but I am looking if I can fix this problem with java 8 with lambda expression or if there is a better solution for this.

 public static String encode(String plaintext ) {
    String str = "";    
    for (int i = 0; i < plaintext.length(); i++) {

        // Counting occurrences of s[i]
        int count = 1;
        while (i + 1 < plaintext.length()
                && plaintext.charAt(i)
                == plaintext.charAt(i + 1)) {
            i++;
            count++;
        }
        str += String.valueOf(count) + plaintext.charAt(i);
    }
    return str;
}

Upvotes: 1

Views: 1256

Answers (2)

aran
aran

Reputation: 11880

As an alternative to Andreas' answer (even if you should only need that):

public static String encode(String input) {
    String output = "";
    String[] cArray = input.replaceAll("(\\w)(?!\\1)", "$1 ").split(" ");
    for (String s : cArray) {
        output += (s.length() + s.substring(0, 1));
    }
    return output;
}

/*
input = GeeeEEKKKss
cArray = ["G", "eee", "EE", "KKK", "ss"]      
output = 1G3e2E3K2s  
*/

Stream version:

public static String encode(String input) {
    return Arrays.stream(
                input.replaceAll("(\\w)(?!\\1)", "$1 ").split(" ")
            )
            .map(s -> s.length() + s.substring(0, 1))
            .collect(Collectors.joining());
}

Upvotes: 4

Andreas
Andreas

Reputation: 159135

Here is one solution using regex and lambda expression, but it requires Java 9 or later.

public static String encode(String plaintext) {
    return Pattern.compile("(.)\\1*").matcher(plaintext)
            .replaceAll(m -> m.group().length() + m.group(1));
}

For full Unicode support, incl. emojis and grapheme clusters, it should be:

public static String encode(String plaintext) {
    return Pattern.compile("(\\X)\\1*").matcher(plaintext)
            .replaceAll(m -> (m.end() - m.start()) / (m.end(1) - m.start(1)) + m.group(1));
}

Upvotes: 4

Related Questions