# Count number of occurences of a digit in the range

Left limit, right limit and the digit to be counted is entered. This code works only for whole numbers i. e. from 0 to n. This code returns the number of occurence of the digit n in the given range. Please review this code and suggest improvements.

#include <iostream>

int count_n(int l, int r, int n)
{
if (r <= l)
{
std::cerr << "Right limit must greater then left limit\n";
return 0;
}

if (l < 0)
{
std::cerr << "Only positive integers\n";
return 0;
}

int count = 0;
for (int i = l; i <= r; ++i)
{
int i_copy = i;
while (i_copy != 0)
{
if (i_copy % 10  == n)
{
count++;
}
i_copy = i_copy / 10;
}
}
return count;
}

int main()
{
int left_limit, right_limit, num;
std::cout << "Enter left limit, right limit and the number(Only positive numbers)\n";
std::cin >> left_limit >> right_limit >> num;

int result = count_n(left_limit, right_limit, num);
std::cout << result << "\n";
}


Output:

Enter left limit, right limit and the number(Only for positive numbers)
1 20 0
2

• There is a much better algorithm. See this answer for some hints as to how to derive it. – Edward Oct 27 '19 at 18:09

In addition to this, you should specify validation for n ( digit ). Also, it may be better to group validations into separate function.

void check_input(int min_left, int max_right, int digit) {
if (max_right <= min_left)
throw std::invalid_argument("right is <= left, expected right > left");
if (min_left < 0)
throw std::invalid_argument("left < 0, expected left > 0");
if (digit <= 0)
throw std::invalid_argument("digit <= 0");
//throw std::invalid_argument("number <= 0");
if (digit > 9)
throw std::invalid_argument("digit > 9");

////number:
//if (digit > max_right)
//  throw std::invalid_argument("number > right limit");
}

int count_digit_entries(int min_left, int max_right, int digit) {
//...
}

int main() {
int left_limit, right_limit, num;
std::cout << "Enter left limit, right limit and the number(Only positive numbers)\n";
std::cin >> left_limit >> right_limit >> num;

check_input(left_limit, right_limit, num);

int result = count_digit_entries(left_limit, right_limit, num);

std::cout << "\nTotal: " << result << "\n";
}


You may want to find not only digits but a whole numbers.

//...

#define DEBUG
#ifdef  DEBUG
#define debug(x) x
#else
#define debug(x)
#endif

int count_digit_entries(int min_left, int max_right, int search_number) {
int count = 0;

int mod = 10;
while(search_number / mod > 0) mod = mod * 10; // 279 -> 1000

for (int current_number = min_left, right = max_right; current_number < right; ++current_number) {
int copied_current_number = current_number; // 542793

while (copied_current_number >= search_number) {
// 542793 - 279 % 1000    >0
// 54279 - 279 % 1000     =0

if ( ( (copied_current_number - search_number) % mod ) == 0 ) {
debug(std::cout << current_number << " ");
++count;
};
copied_current_number = copied_current_number / 10;
// 542793 -> 54279

};
};

return count;
};


Output:

Enter left limit, right limit and the number(Only positive numbers)
0 1000 25
25 125 225 250 251 252 253 254 255 256 257 258 259 325 425 525 625 725 825 925
Total: 20


### 1. Error handling

Since 0 could also be a valid result for the input (e.g. 6 10 5), I'd prefer to indicate invalid input via exceptions rather than the return value:

int count_n(int l, int r, int n) {
if (r <= l) {
throw std::invalid_argument("Right limit must greater then left limit");
}

if (l < 0) {
throw std::invalid_argument("Only positive integers");
}

// ...
}


Thus the caller of the function can distinguish invalid input parameters from valid results by putting the call of count_n() into a try / catch block.

### 2. Function and parameter naming

Naming the function count_n() and the parameter for the digit to count n is a bit unclear.
You should rather use the signature

 int count_digit(int min_left, int max_right, int digit);


to make the intend of that function clearer.