-3

I have the following code:

public static void main(String[] args) {
    StringBuilder phoneNumber = new StringBuilder("828-707-5634");
    for(int i = 0; i < phoneNumber.length(); i++)
    {
      if (phoneNumber.charAt(i) == '-')
        phoneNumber.deleteCharAt(i--);
    }

    System.out.print(phoneNumber);
}

Indeed this removes the dash from the phone number, but intuitively I would have expected it to remove the character just before the dash (because of the --). How/why does this work? Additionally, I find that if I use ++ or omit the increment/decrement entirely the dashes are still removed.

Mark Locklear
  • 5,044
  • 1
  • 51
  • 81
  • 2
    you are changing the object during inspecting its content in the for loop.... – ΦXocę 웃 Пepeúpa ツ Oct 31 '17 at 12:52
  • `i--` feeds the unchanged `i` to the method and afterwards decrements the value. It is the same as if you would call `deleteCharAt(i); i--;`. The `--i` operator does decrement it before feeding the method. – Zabuzard Oct 31 '17 at 12:53
  • 1
    If you want it to delete de character before the dash, use ```--i``` – Artur Trapp Oct 31 '17 at 12:53
  • stop using inline postfix and infix operations. – luk2302 Oct 31 '17 at 13:00
  • 1
    To be fair, this is a "correct" solution to decrement the index since you update the String directly. But I prefer to simply read from the end, that way I don't have to bother with the new length. – AxelH Oct 31 '17 at 13:08

1 Answers1

2

deleteCharAt receives the unincremented value of i, since the value of the expression i-- is the unincremented value. That's why your code works, even though you are relying on the increment expression of the for loop to compensate for a rather contrived and meaningless decrease in i. That all seems rather crude to me, and having i as -1 which will happen if the first character is a dash will raise eyebrows during debugging.

It's probably best to use the replace method in java.lang.String. See replace String with another in java

Else I'd prefer

for (int i = 0; i < phoneNumber.length(); /*intentionally empty*/){
    if (phoneNumber.charAt(i) == '-'){
        phoneNumber.deleteCharAt(i);
    } else {
        ++i;
    }
}

although this is still an O(N2) solution to an O(N) problem due to the repeated evaluation of length()! That can be solved by running the loop backwards, which will also reduce the number of element shuffles:

for (int i = -1 + phoneNumber.length(); i >= 0; /*intentionally empty*/){
    if (phoneNumber.charAt(i) == '-'){
        phoneNumber.deleteCharAt(i);
    } else {
        --i;
    }
}
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • "_Indeed this removes the dash from the phone number, but intuitively I would have expected it to remove the character just before the dash (because of the --)_ Lumbee " Seems your first statement answer OP question perfectly. – AxelH Oct 31 '17 at 13:03
  • 1
    Since you've added your prefered solution, for this kind of code I prefer with `for(int i = phoneNumber.length() -1; i >= 0; --i) ...` – AxelH Oct 31 '17 at 13:09
  • 1
    @AxelH: Yes that cuts down on the amount of shuffling. – Bathsheba Oct 31 '17 at 13:10
  • You shoud always decrement here, if not might end up with an `OutOfBoundsException` and we already checked the character that will come in that position PS :I like the `-1` before the length, simple but much more readable – AxelH Oct 31 '17 at 13:15