Reputation: 121
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
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
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