Home > Software engineering >  How to scan for odd digits in an integer, starting from the first?
How to scan for odd digits in an integer, starting from the first?

Time:10-30

I need the user to input an integer with indefinite number of digits, and then I have to show all the odd digits in this integer starting from the first digit.

long long num, a;
cin >> num;

while (num > 0)
{
    a = num % 10;
    num = num / 10;

    if (a % 2 != 0)
    {
        cout << a;
    }
}

This code shows all the odd digits but from the end of the integer.

CodePudding user response:

When a 'natural' sequence of events or operations leads you to get the correct results but in reverse order, then a stack is most likely the simplest tool to fix things.

Simply push each value onto the stack as you generate them; and then, when done, just run through that stack, and pop (and display) its contents until the stack is empty.

Here's a version of your code using the std::stack container:

#include <iostream>
#include <stack>

int main()
{
    long long num, a;
    std::cin >> num;
    std::stack<long long> digits;
    while (num > 0) {
        a = num % 10;
        if (a % 2) digits.push(a);
        num = num / 10;
    }
    while (!digits.empty()) {
        std::cout << digits.top();
        digits.pop();
    }
    std::cout << std::endl;
    return 0;
}

There will be more efficient code solutions, for sure, but the above is both easy to implement and clearly understandable.


Note that, as pointed out by user4581301, the above code uses the long long data type, which has a limited size (that solution is based on the code you gave). However, if you truly want an arbitrary, indefinite number of digits (with no implied size limit), then you can read your input as a string and process that.

This also makes the solution much simpler, as the 'natural' analysis of that string will produce the results in the correct order, and you only need 'copy' the relevant (i.e. odd) digits from one string to another:

#include <iostream>
#include <string>

int main()
{
    // (1) Read "arbitrary length" number as a string ...
    std::string number;
    std::cin >> number;
    // (2) Create a new string and append all odd digits to it ...
    std::string digodd{};
    for (auto c : number) {
        if (!isdigit(c)) {
            // Error handling for bad input ...
            std::cout << "Error: Non-digit found!";
            return -1;
        }
        auto digit = c - '0'; // Guaranteed to work by the Standard
        if (digit % 2) digodd  = c;
    }
    // (3) Display the result string... 
    std::cout << digodd << std::endl;
    return 0;
}

CodePudding user response:

I mean, technically, based on how the question is phrased, the answer is this. Works for an indeterminate number of digits - even more than available RAM:

#include <iostream>
#include <conio.h>

int main()
{
    while (true)
    {
        auto ch = (const char)_getch();
        if ( (ch == '1') || (ch == '3') || (ch == '5') || (ch == '7') || (ch == '9') )
        {
            std::cout << ch;
        }
    }
}

CodePudding user response:

If you are not considering negative numbers then it makes more sense to declare the variable num as having the unsigned integer type unsigned long long int.

A simple way to do the task is to write a recursive function.

Here is a demonstration program. As the user input I am using the maximum value of an object of the type unsigned long long int.

#include <iostream>
#include <limits>

std::ostream & output_odd_digits( unsigned long long int num, 
                                  std::ostream &os = std::cout )
{
    const unsigned long long int Base = 10;
    
    unsigned long long int digit = num % Base;
    
    if (  num / Base != 0 )
    {
        output_odd_digits( num / Base, os );
    }

    if ( digit % 2 != 0  ) os << digit;
    
    return os;
}

int main() 
{
    unsigned long long int num = std::numeric_limits<unsigned long long int>::max();
    
    std::cout << num << '\n';
    
    output_odd_digits( num ) << '\n';
    
    return 0;
}

The program output is

18446744073709551615
17737955115

A non-recursive function can look the following way

#include <iostream>
#include <limits>

std::ostream & output_odd_digits( unsigned long long int num, 
                                  std::ostream &os = std::cout )
{
    const unsigned long long int Base = 10;
    
    unsigned long long int n = 1;
    
    for ( unsigned long long int tmp = num; tmp / Base != 0; tmp /= Base )
    {
        n *= Base;
    }
    
    for ( ; n != 0; n /= Base )
    {
        unsigned long long int digit = num / n;
        
        if ( digit % 2 != 0 ) os << digit;
        
        num %= n;
    }
    
    return os;
}

int main() 
{
    unsigned long long int num = std::numeric_limits<unsigned long long int>::max();
    
    std::cout << num << '\n';
    
    output_odd_digits( num ) << '\n';
    
    return 0;
}

The program output is the same as shown above

18446744073709551615
17737955115

As you can see in the both cases there is no any need to use a standard container that occupies an additional memory.

Here is one more demonstrative program where a separate function is not used.

#include <iostream>

int main() 
{
    const unsigned long long int Base = 10;

    while ( true )
    {
        unsigned int num;
        
        std::cout << "Enter a non-negative number (0 - exit ): ";
        
        if ( !( std::cin >> num ) || ( num == 0 ) ) break;
        
        unsigned long long int n = 1;
    
        for ( unsigned long long int tmp = num; tmp / Base != 0; tmp /= Base )
        {
            n *= Base;
        }
    
        for ( ; n != 0; n /= Base )
        {
            unsigned long long int digit = num / n;
        
            if ( digit % 2 != 0 ) std::cout << digit;
        
            num %= n;
        }
        
        std::cout << '\n';
    }

    return 0;
}

The program output might look like

Enter a non-negative number (0 - exit ): 1234567890
13579
Enter a non-negative number (0 - exit ): 0
  • Related