Tuesday, April 13, 2010

CodingBat string manipulation problems - Extra

This part includes solutions that I didn't come up with, my own variants of the original problems, exercising variations on previous regex solutions, etc.

A little help

plusOut: Given a string and a non-empty word string, return a version of the original string where all chars have been replaced by pluses ("+"), except for appearances of the word string which are preserved unchanged.
public String plusOut(String str, String word) {
  return str.replaceAll(
    "(?<!(?=word).{0,M})."
      .replace("word", java.util.regex.Pattern.quote(word))
      .replace("M", String.valueOf(word.length()-1)),
    "+"
  );  
}
Credit to Alan Moore on stackoverflow for this last one.
repeatEnd/Begin: Given a string and an int N (whose value is no more than the length of the string), return a string made of N repetitions of the last/first N characters of the string.
"(?=.{0,N}$(?<=(.{N}))).|." // repeatEnd
".(?<=^(?=(.{N})).{0,N})|." // repeatBegin
This is the regex only; see Part 3 for the rest of the solution.

Variations on a theme

backAround: Given a string, take the last char and return a new string with the last char added at the front and back.
replaceAll("(.+)(?<=(.))", "$2$1$2");
replaceAll("^(.*)(?<=(.))$", "$2$1$2");
replaceAll("(.*)(.)", "$2$1$2$2");
replaceAll("((.*)(.))", "$3$1$3");
replaceAll("((?:.*)(.))", "$2$1$2");
replaceAll("(?:^|$)(?=.*(?<=(.)))", "$1");

deFront: Given a string of any length, return a version without the first 2 chars. Except keep the first char if it is 'a' and keep the second char if it is 'b'.
replaceAll("((a)|.)((b)|.)(.*)", "$2$4$5");
replaceAll("(?:(a)|.)(?:(b)|.)(.*)", "$1$2$3");
replaceAll("(?=(a?)).(?=(b?)).(.*)", "$1$2$3");
replaceAll("^(?=(a?)).(?=(b?)).", "$1$2");
replaceAll("(?<=^)[^a]|(?<=^.)[^b]", "");

No comments:

Post a Comment