2

I wrote this function as part of interview practice. This method removes a character from a given string.

I was wondering how I could make this code more efficient when it comes to runtime/space. I think my code is O(n) and I'm not sure if I can increase the efficiency. However, perhaps using things such as StringBuffer or StringBuilder would increase it a bit? Not sure as I'm still a bit new to Java.

public static String takeOut(String str, char c) {
    int len = str.length();
    String newstr = "";
    for (int i = 0; i < len; i++) {
        if (str.charAt(i) != c) {
            newstr = newstr + str.charAt(i);
        }
    }
    return newstr;
}
Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
Liondancer
  • 15,721
  • 51
  • 149
  • 255
  • 4
    No, this is definitely *not* O(n). Think about what `newstr = newstr + str.charAt(i)` needs to do. Imagine all n characters aren't the one you're looking for. (And yes, StringBuilder is what you're looking for.) See http://yoda.arachsys.com/java/stringbuffer.html - written ages ago, but just replace `StringBuffer` with `StringBuilder` everywhere. – Jon Skeet Feb 28 '14 at 08:07
  • what about `replaceAll()`? – shyos Feb 28 '14 at 08:09
  • 1
    why not use `str.replaceAll(c+"","")`? – makata Feb 28 '14 at 08:11
  • I should have mentioned in the question to try and not use replaceAll as part of the challenge – Liondancer Feb 28 '14 at 08:12
  • Have you seen [this question?](http://stackoverflow.com/questions/8894258/fastest-way-to-iterate-over-all-the-chars-in-a-string) – makata Feb 28 '14 at 08:18
  • @mek nope But ill take a look now! – Liondancer Feb 28 '14 at 08:25

4 Answers4

3

Strings are immutable in Java, so your answer actually results in len number of strings being created. Which means they are copied len times, so you have O(N*N) code here. StringBuilder is definitely a better approach.

public static String takeOut(String str, char c) {
    int len = str.length();
    StringBuilder newstr = new StringBuilder();
    for (int i = 0; i < len; i++) {
        if (str.charAt(i) != c) {
            newstr.append((char)str.charAt(i));
        }
    }
    return newstr.toString();
}

A simpler approach would be to use the built in function:

public static String takeOut(String str, char c) {
    return str.replace(String.valueOf(c), "");
}
Daniel
  • 4,481
  • 14
  • 34
2

StringBuilder would definitely prevent your code from creating new strings with every iteration. Additionally, is the character to be removed contained only once in the string? Then you could break the for loop after the first match. Also, locally store the result of String#charAt to not call the method twice.

Smutje
  • 17,733
  • 4
  • 24
  • 41
2

Have you tried

str.replaceAll(c,"");

? Maybe the Java-Runtime kows the fastest way of replacing (deleting)...

user987339
  • 10,519
  • 8
  • 40
  • 45
user3363881
  • 101
  • 1
  • 5
1

My suggestion to replace any char more efficiently would be:

1) Convert the String to a char[] array.

2) Run through the array, testing each character one by one and replacing it if needed and append in StringBuilder

I think this is probably the fastest performance you will get in pure Java.

Kick
  • 4,823
  • 3
  • 22
  • 29