0

So I need to remove duplicates of a specific string from another string in Java, a few examples:

'test12312312312'       -> Remove duplicates of '123', output -> 'test12312'
'my sentence-!!!!!!!!!' -> Remove duplicates of '!!' , output -> 'my sentence-!!!'
'3rd ?!?!?!abd%3!?!?!??'-> Remove duplicates of '!?' , output -> '3rd ?!?!abd%3?'

Hopefully those examples make this clear. e.g. you pass a function any two strings, and it removes all duplicates of the first one from the second. For example it might look like:

String removeDuplicates(String checkString, String message) {
    //Return 'message' with duplicates of 'checkString' removed
}

I've seen various implementations of this for removing all instances of the string, or removing duplicates of a specific character - but none that keep the first occurance of a string. Any ideas?

  • Where is your code? What have you tried? – brso05 Oct 18 '16 at 20:23
  • 6
    I'm voting to close this question as off-topic because [questions asking for homework help must include a summary of the work done so far to solve the problem, and a description of the difficulty solving it](http://stackoverflow.com/help/on-topic). – Andreas Oct 18 '16 at 20:24
  • Did you read this? http://stackoverflow.com/questions/4989091/removing-duplicates-from-a-string-in-java – mischka Oct 18 '16 at 20:24
  • Second example is wrong. If you remove *duplicate* `!!` values then `!! !! !! !! !` (spaces added for clarity) becomes `!! !`, i.e. the three duplicates of `!!` has been removed, leaving the first instance, so the result is `'my sentence-!!!'` (3 bangs, not 1). – Andreas Oct 18 '16 at 20:32

4 Answers4

1

With String#replace:

String needle = /* search string */;
String base = /* input string */;
int firstLoc = base.indexOf(needle);
if (firstLoc > 0) {
    int cutoff = firstLoc + needle.length();
    return base.substring(0, cutoff) + base.substring(cutoff).replace(needle, "");
}
return base;

Outside of that, you can iterate through the string, and if the first character of your search string matches the current character you are at, see if the remainder makes up the string in total. If it does, then just skip ahead. You're essentially just rebuilding the string:

//Precondition: needle not empty, vars not null, etc
StringBuilder back = new StringBuilder();
String needle = /* search string */;
String base = /* input string */;
boolean first = true;
for (int i = 0; i < base.length(); i++) {
    char c = base.charAt(i);
    if (c == needle.charAt(0)
          && base.substring(i, Math.min(base.length(), i + needle.length())).equals(needle)) {
        if (first) {
            first = false;
        } else {
            i += needle.length() - 1;
            continue;
        }
    }
    back.append(c);
}
return back.toString();
Rogue
  • 11,105
  • 5
  • 45
  • 71
  • That removes *all* instances, not just the duplicates. First instance of `needle` has to remain in the result. – Andreas Oct 18 '16 at 20:50
  • Whoops, you're correct. I missed that they wanted to keep the first. Updated. – Rogue Oct 18 '16 at 20:55
0
String removeDuplicates(String checkString, String message) {
    return checkString.replaceAll("("+message+")+", message);
}

this will leave a single message behind in a chain of message. this only works if they are followed immediately by one another.

Wicpar
  • 195
  • 3
  • 13
  • Why call `replace` twice? Why not 3 times, 4 times, ...? – Andreas Oct 18 '16 at 20:53
  • You have to do it twice as replace continues replacing after reinserting the new string in the string to avoid infinite loops, leaving half of the instances of the duplicates, running it a second time leaves only one. – Wicpar Oct 20 '16 at 07:05
  • `removeDuplicates("ABABABABABABABABABAB", "AB")` returns `ABABAB`. That's not right. --- Also, you have parameters reversed. See comment in question code: *//Return 'message' with duplicates of 'checkString' removed*. – Andreas Oct 20 '16 at 07:09
  • my bad, mistook the replace of java with the one in js. – Wicpar Oct 20 '16 at 12:09
  • See third example in question. Your updated code will fail terribly on it. And you still have the parameters reversed. *(wish I could down-vote again)* – Andreas Oct 20 '16 at 16:06
  • What's fun about getting everything chewed in mummy's mouth? I will not reverse the parameters in your honor, as it is standard to put the object before the modifier. – Wicpar Oct 20 '16 at 21:17
  • That's ok. If you want to leave a useless (i.e. incorrect) answer, that's your prerogative. And I'm not talking about parameter order when I say *incorrect*. – Andreas Oct 20 '16 at 21:35
  • You are dragging me down and beating me with experience, good job. – Wicpar Oct 20 '16 at 22:02
0

I see 2 ways:

  1. Find first occurence of your substring. If there's no occurence, return input string. If there is such occurence, save everything up to that point (together with that occurence), remove all occurences further in input string.

  2. Split input text on repeated string. Return result[0] + repeated + rest.join("")

Not sure which way will be faster.

Filip Malczak
  • 3,124
  • 24
  • 44
0

Here is an implementation that gives you the output in the updated examples.

private static String removeDuplicates(String checkString, String message) {
    int idx = message.indexOf(checkString); // Find first occurrence of checkString
    if (idx == -1)
        return message; // No occurrence of checkString found
    idx += checkString.length(); // Skip first occurrence of checkString
    StringBuilder buf = new StringBuilder(message);
    while ((idx = buf.indexOf(checkString, idx)) != -1)
        buf.delete(idx, idx + checkString.length());
    return buf.toString();
}

It's not the most optimal way of doing it, but it is a fairly simple solution.

Test

System.out.println(removeDuplicates("123", "test12312312312"));
System.out.println(removeDuplicates("!!", "my sentence-!!!!!!!!!"));
System.out.println(removeDuplicates("!?", "3rd ?!?!?!abd%3!?!?!??"));

Output

test12312
my sentence-!!!
3rd ?!?!abd%3?
Andreas
  • 154,647
  • 11
  • 152
  • 247