HN Learner
HN Learner

Reputation: 614

How to break an int into digits and assign digits to a vector in same order?

I am using a Constructor to take an unsigned int as an argument, break it into digits and assign the appropriate true and false values to a vector object. But the problem is that, my poor logic assigns the values in reverse order as the last digit is separated first and so on. The Code I have written is:

vector<bool> _bits; 
uBinary(unsigned int num){  
    int i = 1;
    while(num > 0)
    {
        int d = num%10;
        num /= 10;
        _bits.resize(i++);
        if(d == 1)
        {
            _bits[_bits.size() - 1] = true; 
        }
        else if(d==0)
        {
            _bits[_bits.size() - 1] = false;
        }
    }
}

For example: if argument 10011 is passed to the function uBinary() the vector object will be assigned the values in this order 11001 or true,true,false,false,true which is reversed. All I need to do here is that, I want to assign the values without reversing the order and I don't want to use another loop for this purpose.

Upvotes: 1

Views: 82

Answers (2)

NathanOliver
NathanOliver

Reputation: 180500

One way you can do the reversing with another loop or std::reverse is to use recursion. With recursion you can walk down the int until you hit the last digit and then you add the values to the vector as the calls return. That would look like

void uBinary(unsigned int num)
{   
    if (num == 0)
        return;
    uBinary(num / 10);
    _bits.push_back(num % 10 ? true : false);
}

Which you can see working with

int main()
{
    uBinary(10110);
    for (auto e : _bits)
        std::cout << e << " ";
}

Live Example


Do note that it is advisable not to use leading underscores in variables names. Some names are reserved for the implementation and if you use one it is undefined behavior. For a full explanation of underscores in names see: What are the rules about using an underscore in a C++ identifier?

Upvotes: 1

Cameron
Cameron

Reputation: 98746

One way is to start at the highest possible digit (unsigned int can only hold values up to 4294967295 on most platforms) and ignore leading zeros until the first actual digit is found:

for (uint32_t divisor = 1000000000; divisor != 0; divisor /= 10) {
    uint32_t digit = num / divisor % 10;
    if (digit == 0 && _bits.size() == 0 && divisor != 1)
        continue;  // ignore leading zeros
    _bits.push_back(digit == 1);
}

But finding the digits in reverse and then simply reversing them is much simpler (and at least as efficient):

do {
    _bits.push_back(num % 10 == 1);
    num /= 10;
} while (num != 0);
std::reverse(_bits.begin(), _bits.end());

Upvotes: 2

Related Questions