Следующий код вычисляет общее количество цифр в десятичных числах для всех целых чисел от 1 до n
:
int Digits = 0;
int LeadingZeros = 0;
for (int t = n; 0 < t; t /= 10)
{
++Digits;
LeadingZeros = 10*LeadingZeros + 1;
}
int TotalDigits = Digits * (n+1) - LeadingZeros;
Причина: цикл вычисляет количество цифр в n
, помещая это число в Digits
. Если бы мы записали все целые числа от 0 до n
в виде десятичных чисел с Digits
цифрами (с использованием начальных нулей, таких как «003»), то было бы использовано Digits * (n+1)
цифр. Из этого мы хотим вычесть количество ведущих нулей. (Для нуля мы хотим вычесть все его нули, чтобы он не оказывал никакого влияния на наш счет.)
Для n
от 1 до 9 вычитается только один «0», а для 0. Для n
от 10 до 99 мы хотим вычесть 9 ведущих нулей из «01» в « 09 », а также два нуля в« 00 ». Таким образом, от 10 до 99 мы вычитаем тот же один ведущий ноль, что и для n
в 1 к 9, но также и еще десять ведущих нулей. Аналогично, для n
от 100 до 999 мы вычитаем эти ведущие нули плюс еще 100 - еще один для каждого числа от 0 до 99. В конечном счете, число LeadingZeros - это число 111 ... 111 с тем же количеством цифр, что и n
. Мы видим, что цикл вычисляет это в LeadingZeros
, поэтому общее количество используемых цифр равно Digits * (n+1) - LeadingZeros
.
При подготовке буфера для этих цифр, должен быть добавлен еще один символ для завершающего нуля. Кроме того, sprintf(my_numbers_as_a_string, "%d", i);
запишет новый номер в начало my_numbers_as_a_string
. Для объединения новых номеров необходимо предусмотреть возможность записи до конца предыдущих номеров.