1

Lets say I have a string "aabbccaa". Now I want to replace occurrences of "aa" in given string by another string. But it should be in following way.

First occurrence of "aa" should be replaced by "1" and next occurrence of "aa" by "2" and so on.

So, the result of the string becomes "1bbcc2".

bagrat
  • 7,158
  • 6
  • 29
  • 47
hatellla
  • 4,796
  • 8
  • 49
  • 101

4 Answers4

10

You can use replaceFirst() in a for loop where counter is incrementing...

for (int i = 1; string.contains("aa"); i++) {
    string = string.replaceFirst("aa", "" + i);
}
Vitalii Elenhaupt
  • 7,146
  • 3
  • 27
  • 43
sgpalit
  • 2,676
  • 2
  • 16
  • 22
  • 1
    Seems like better to use `StringBuilder` to prevent creation a new `String` each time a pattern found. – Vitalii Elenhaupt May 26 '15 at 13:43
  • 1
    Problem with this one is it's time complexity. This is clearly an `O(n)` problem, but this code searches the string from the beginning every time, even if you know you have already dealt with that section of string. Making it `O(n*r)` where r is the number of replacements to be done. – weston May 26 '15 at 13:45
  • @weston yes you are right but the question is simple and the answer is simple. If he/she wants to make it more performancer and complexer that is her/his responsibility :) – sgpalit May 26 '15 at 13:47
  • 1
    I only comment because as the answer with the most votes, it's more important to point out it's drawbacks. – weston May 26 '15 at 13:52
5

You can do it using the Matcher's appendReplacement method:

Pattern p = Pattern.compile("aa");
Matcher m = p.matcher("aabbccaahhhaahhhaaahahhahaaakty");
StringBuffer sb = new StringBuffer();
// Variable "i" serves as a counter. It gets incremented after each replacement.
int i = 0;
while (m.find()) {
    m.appendReplacement(sb, ""+(i++));
}
m.appendTail(sb);
System.out.println(sb.toString());

This approach lets you avoid creating multiple string objects (demo).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

It is possible to do using Java functions but using a char array and doing it using a lower level of logic would be faster.

String s = "aabbccaa";
String target = "aa";
int i = 1;
String newS;

for (int j = 0; j < s.length; j++) {
  newS = s.replaceFirst(target, i++);
  j += newS.length - s.length;
  s = newS;
}
Brett Walker
  • 3,566
  • 1
  • 18
  • 36
  • curious question, i know this is obviously a time complexity of O(n) due to the for loop, but where did you find the complexity of the java built in functions? Since I am sometimes curious if the way of manually writing something or of using a java built in function is faster. – jgr208 May 26 '15 at 13:29
  • 1
    The `replaceFirst` method uses Regular Expressions to do its work. While very useful and fancy they do incur a runtime penality. For simple pattern matching it might be faster to do it your self. – Brett Walker May 26 '15 at 13:31
0

Here is a solution :

    public static void main(String[] a) {

        int i = 1;
        String before = "aabbccaabbaabbaa";
        String regex = "aa";

        String after = substitute(i, before, regex);

        System.out.println(after);

    }

    private static String substitute(int i, String before, String regex) {

        String after = before.replaceFirst(regex, Integer.toString(i++));

        while (!before.equals(after)) {

            before = after;
            after = before.replaceFirst(regex, Integer.toString(i++));

        }

        return after;

    }

Output : 1bbcc2bb3bb4

romfret
  • 391
  • 2
  • 11