Delete last duplicate line characters

Let's say we have a line like these:

"abcdaaaaefghaaaaaaaaa"
"012003400000000"

I would like to remove the last duplicate characters to get this:

"abcdaaaaefgh"
"0120034"

Is there an easy way to do this with regex? It's somehow hard for me to do this, and my code starts to look like a giant monster ...

Some explanations:

  • What is considered repetitive?

    A sequence of at least 2 characters at the end. One character is not considered repeated. For example: in "aaaa", is 'a'not considered to be repeated, but in "baaaa", it is. Therefore, in the case "aaaa"we do not need to change anything for the string. Another example: "baa"should give "b".

  • And for strings of only one character?

    "a", char 'a', -, .. "a".

+5
5

:

public class Test {
  public void test() {
    System.out.println(removeTrailingDupes("abcdaaaaefghaaaaaaaaa"));
    System.out.println(removeTrailingDupes("012003400000000"));
    System.out.println(removeTrailingDupes("0120034000000001"));
    System.out.println(removeTrailingDupes("cc"));
    System.out.println(removeTrailingDupes("c"));
  }

  private String removeTrailingDupes(String s) {
    // Is there a dupe?
    int l = s.length();
    if (l > 1 && s.charAt(l - 1) == s.charAt(l - 2)) {
      // Where to cut.
      int cut = l - 2;
      // What to cut.
      char c = s.charAt(cut);
      while (cut > 0 && s.charAt(cut - 1) == c) {
        // Cut that one too.
        cut -= 1;
      }
      // Cut off the repeats.
      return s.substring(0, cut);
    }
    // Return it untouched.
    return s;
  }

  public static void main(String args[]) {
    new Test().test();
  }
}

@JonSkeet "spec":

, , . , , , :

"" => ""
"x" => "x"
"xx" => ""
"aaaa" => ""
"ax" => "ax"
"abcd" => "abcd"
"abcdddd" => "abc"

, ?

... aaaa, , . aaaa. :

:

  private String removeTrailingDupes(String s) {
    // Is there a dupe?
    int l = s.length();
    if (l > 1 && s.charAt(l - 1) == s.charAt(l - 2)) {
      // Where to cut.
      int cut = l - 2;
      // What to cut.
      char c = s.charAt(cut);
      while (cut > 0 && s.charAt(cut - 1) == c) {
        // Cut that one too.
        cut -= 1;
      }
      // Cut off the repeats.
      return cut > 0 ? s.substring(0, cut): s;
    }
    // Return it untouched.
    return s;
  }

:

"" => ""
"x" => "x"
"xx" => "xx"
"aaaa" => "aaaa"
"ax" => "ax"
"abcd" => "abcd"
"abcdddd" => "abc"
+3

replaceAll() :

str = str.replaceAll("(.)\\1+$", "");

EDIT

, , , :

public String replaceLastRepeated(String str) {
    String replaced = str.replaceAll("(.)\\1+$", "");
    if (replaced.equals("")) {
        return str;
    }
    return replaced;
}
+9

I don't think I would use a regex for this:

public static String removeRepeatedLastCharacter(String text) {
    if (text.length() == 0) {
        return text;
    }
    char lastCharacter = text.charAt(text.length() - 1);
    // Look backwards through the string until you find anything which isn't
    // the final character
    for (int i = text.length() - 2; i >= 0; i--) {
        if (text.charAt(i) != lastCharacter) {
            // Add one to *include* index i
            return text.substring(0, i + 1);
        }
    }
    // Looks like we had a string such as "1111111111111".
    return "";
}

Personally, I find this easier to understand than regular expression. It may or may not be faster - I would not want to make a prediction.

Note that this always removes the trailing character, whether it is repeated or not. This means that single character strings always end with empty strings:

"" => ""
"x" => ""
"xx" => ""
"ax" => "a"
"abcd" => "abc"
"abcdddd" => "abc"
+3
source

Replace with (.)\1+$an empty line:

"abcddddd".replaceFirst("(.)\\1+$", ""); // returns abc
0
source

This should do the trick:

public class Remover {
     public static String removeTrailing(String toProcess)
     {
        char lastOne = toProcess.charAt(toProcess.length() - 1);
        return toProcess.replaceAll(lastOne + "+$", "");
     } 

     public static void main(String[] args)
     {
        String test1 = "abcdaaaaefghaaaaaaaaa";
        String test2 = "012003400000000";

        System.out.println("Test1 without trail : " + removeTrailing(test1));
        System.out.println("Test2 without trail : " + removeTrailing(test2));
     }
}
0
source

All Articles