2

output should be 12 not 102 why is it not deleting all the zeros

#include<bits/stdc++.h>

using namespace std;

int main()
{
    string s="10002";
    for(int i=0;i<s.size();i++)
    if(s[i]=='0')
    s.erase(s.begin()+i);
    cout<<s;
}
  • 2
    You can use a debugger and step each iteration to see what happens. BTW, in C++20, you can simply write `std::erase(s, '0');`. Until C++20, you can do the same by combining `auto it = std::remove(s.begin(), s.end(), '0');` and `s.erase(it, s.end());`. – Daniel Langr Jun 11 '21 at 05:44
  • also your indentation is terrible and will easily cause confusion – phuclv Jun 11 '21 at 06:05

3 Answers3

3

It’s skipping a value because the loop counter gets incremented even when you erase characters. You need to decrement i when you erase a 0

if (s[i] == 0) {
    s.erase(s.begin() + i);
    i--;
}
cigien
  • 57,834
  • 11
  • 73
  • 112
Dan Mullin
  • 4,285
  • 2
  • 18
  • 34
  • It works, but I don’t really like the underflow in case the string starts with a zero. – Axel Jun 12 '21 at 08:50
  • There won’t be underflow because the loop counter will be reset to zero if the first character is a zero. – Dan Mullin Jun 12 '21 at 11:10
  • I mean, you decrease idx to -1, and then increase it again to 0. It will of course work, but IMHO it's not really elegant, rather some sort of workaround. – Axel Jun 12 '21 at 11:50
  • 1
    I get what you’re saying. It’s a safe little piece of code but it does “feel” dirty – Dan Mullin Jun 12 '21 at 11:58
2

Let's dry run your code.

  1. i = 0, s[0] != '0' (does nothing)
  2. i = 1, s[1] = '0' (it erases the '0' at second index, now the string is "1002")
  3. i = 2, s[2] = '0' (it erases the '0' at third index, now the string is "102")
  4. i = 3, but the size of string is also 3, so the loop breaks because of the condition i<s.size().

Hence 102 is printed.

potter1024
  • 210
  • 1
  • 10
1

As @DanMulin mentioned, it's skipping value because when you deleted a character, the std::string size is decreased but i keeps getting increased. To solve it, add a i--.

#include <iostream>
#include <string>

int main()
{
    std::string s="10002";
    for(int i=0; i<s.size(); i++)
    {
        if(s[i]=='0')
        {
            s.erase(s.begin()+i); i--;
        }
    }
    std::cout << s;
}

Or to avoid this all together, you can use a while loop instead (which I recommended more when manipulating std::strings):

#include <iostream>
#include <string>

int main()
{
    std::string s="10002";
    int inc = 0;
    while(inc < s.length())
    {
        while(s[inc] == '0') { s.erase(s.begin()+inc); }
        inc++;
    }
    std::cout << s;
}

Also, see

silverfox
  • 1,568
  • 10
  • 27