codingBat plusOut using regex

前端 未结 4 1060
离开以前
离开以前 2020-12-12 01:20

This is similar to my previous efforts (wordEnds and repeatEnd): as a mental exercise, I want to solve this toy problem using regex only.

Description from codingbat.

相关标签:
4条回答
  • 2020-12-12 01:55

    An extremely simple solution, using \G:

    word = java.util.regex.Pattern.quote(word);
    return str.replaceAll("\\G((?:" + word + ")*+).", "$1+");
    

    However, there is a caveat. Calling plusOut("12xxxxx34", "xxx") with the implementation above will return ++xxx++++.

    Anyway, the problem is not clear about the behavior in such case to begin with. There is even no test case for such situation (since my program passed all test cases).

    The regex is basically the same as the looping solution (which also passes all test cases):

    StringBuilder out = new StringBuilder(str);
    
    for (int i = 0; i < out.length(); ) {
        if (!str.startsWith(word, i))
            out.setCharAt(i++, '+');
        else
            i += word.length();
    }
    
    return out.toString();
    

    Repeatedly skips the word, then replace the current character if it is not prefix of word.

    0 讨论(0)
  • 2020-12-12 01:55

    I think you could leverage a negated range to do this. As this is just a hint, it's not tested though!

    Turn your "xy" into a regexp like this: "[^xy]"

    ...and then wrap that into a regexp which replaces strings matched by that expression with "+".

    0 讨论(0)
  • 2020-12-12 02:01

    This is provided here just for reference. This is essentially Alan's solution, but using replace instead of String.format.

    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)),
        "+"
      );  
    }
    
    0 讨论(0)
  • 2020-12-12 02:03

    This passes all their tests:

    public String plusOut(String str, String word) {
      return str.replaceAll(
        String.format("(?<!(?=\\Q%s\\E).{0,%d}).", word, word.length()-1),
        "+"
      );  
    }
    

    Also, I get:

    plusOut("1xAxAx2", "xAx") → "+xAxAx+"
    

    If that's the result you were looking for then I pass your overlap test as well, but I have to admit, that one's by accident. :D

    0 讨论(0)
提交回复
热议问题