Search code examples
c++numbersdigits

C++ - Counting digits of a range of numbers


What I need to do:

A program where the user inputs a range of numbers from S to K. It should count the amount of times a digit is found among the numbers, and finally print them out in the following order: 0 1 2 3 4 5 6 7 8 9.

My code:

OBS: It's not working for digits over 10.

#include <iostream>

using namespace std;

int main()
{
int S, K;
cin >> S >> K;
int digits = 0;
int dig0 = 0;
int dig1 = 0;
int dig2 = 0;
int dig3 = 0;
int dig4 = 0;
int dig5 = 0;
int dig6 = 0;
int dig7 = 0;
int dig8 = 0;
int dig9 = 0;
int remainder = 0;

for (int i = S; i <= K; i++) {
    if (i < 10) {
        switch(i) {
        case 0:
            dig0++;
            break;
        case 1:
            dig1++;
            break;
        case 2:
            dig2++;
            break;
        case 3:
            dig3++;
            break;
        case 4:
            dig4++;
            break;
        case 5:
            dig5++;
            break;
        case 6:
            dig6++;
            break;
        case 7:
            dig7++;
            break;
        case 8:
            dig8++;
            break;
        case 9:
            dig9++;
            break;
        }
    } else if (i >= 10) {
        while (i > 0) {
            remainder = i % 10;
            switch(remainder) {
            case 0:
                dig0++;
                break;
            case 1:
                dig1++;
                break;
            case 2:
                dig2++;
                break;
            case 3:
                dig3++;
                break;
            case 4:
                dig4++;
                break;
            case 5:
                dig5++;
                break;
            case 6:
                dig6++;
                break;
            case 7:
                dig7++;
                break;
            case 8:
                dig8++;
                break;
            case 9:
                dig9++;
                break;
            }
            i /= 10;
        }
    }
}

cout << dig0 << ' ' << dig1 << ' ' << dig2 
<< ' ' << dig3 << ' ' << dig4 << ' ' << dig5 
<< ' ' << dig6 << ' ' << dig7 << ' ' << dig8 << ' ' << dig9;

return 0;
}

Desired behaviour:

Test case 01

Input: 1 to 9

Output: 0 1 1 1 1 1 1 1 1 1 (Since there are 0 digits of 0, and 1 digit of each number from 1 to 9)

Test case 02

Input: 767 772

Output: 1 1 1 0 0 0 3 10 1 1


Solution

  • (edit to allow any values for S and K including negative)

    Can be

    #include <iostream>
    using namespace std;
    
    int main()
    {
      int S, K;
      int dig[10] = { 0 };
    
      if (!(cin >> S >> K))
        return -1;
    
      if (S > K)
        swap(S, K);
    
      for (auto i = S; i <= K; ++i) {
        auto v = i;
    
        do {
          dig[abs(v % 10)] += 1;
          v /= 10;
        } while (v != 0);
      }
    
      for (auto v : dig)
        cout << v << ' ';
      cout << endl;
    
      return 0;
    }
    

    I did some change from your proposal

    • the correction is to let i unchanged in the internal while using an other variable.
    • I check two valid values are enter (if (!(cin >> S >> K)) ...)
    • If needed I exchange S and K to have S <= K because this is the assumption in the for below
    • I use an array rather than dig0 dig1 ... dig9, this is much more simple with an array
    • I manage negative values. Note I do int v = i; ... dig[abs(v % 10)] += 1; rather than int v = abs(i); ... dig[v % 10] += 1; to manage the case where v is INT_MIN ( -INT_MIN equals INT_MIN so is still negative when using complement to 2)

    Compilation and executions :

    pi@raspberrypi:/tmp $ g++ -pedantic -Wextra m.cc
    pi@raspberrypi:/tmp $ ./a.out
    1 9
    0 1 1 1 1 1 1 1 1 1 
    pi@raspberrypi:/tmp $ ./a.out
    767 772
    1 1 1 0 0 0 3 10 1 1 
    pi@raspberrypi:/tmp $ ./a.out
    -1 1
    1 2 0 0 0 0 0 0 0 0 
    pi@raspberrypi:/tmp $ ./a.out
    -767 -772
    1 1 1 0 0 0 3 10 1 1 
    

    Additional note : if the auto disturb you replace them by int, and for (auto v : dig) cout << v << ' '; by for (int i = 0; i != 10; ++i) cout << dig[i] << ' ';