Как я уже упоминал в своем комментарии, это больше вопрос проектирования алгоритма, чем программирования на C или обработки строк.Возможно, самый простой способ приблизиться к этому - представить строку как состоящую из нескольких «блоков» чисел.
- блок 1 состоит из чисел 1 - 9 и начинается со смещения 0
- блок 2 содержит числа 10 - 99 и начинается со смещения 9
- блок 3 содержит числа 100 - 999 и начинается со смещения 189
- и т. д.
Поскольку мыЗная смещение каждого блока, мы можем вычислить смещение в блоке , которому соответствует глобальное смещение k
.
Например, если k = 207
, мы знаем, что соответствующая цифра должнаначинаются в блоке 3 (диапазон номеров от 100
до 999
) и что его смещение в этом блоке равно 207 - 189 = 8
.Поскольку каждое число в этом блоке имеет 3 цифры, смещение 8 должно соответствовать третьему числу в блоке - то есть 102
.А так как остаток от 8, деленный на 3, равен 2, мы знаем, что ищем третью цифру в этом номере (индексы начинаются с 0).
Картинка поможет объяснить это - но уже поздно, поэтому...
В коде ...
static char find_kth_digit(int k) {
int offset = 0; // Global offset
int block_length = 0; // Length of current 'block'
int offset_inner = 0; // Offset within current block
// Power to which 10 is currently raised
int l = 1;
int start = 1, end = 10; // start / end of current block
char digit = '0'; // result
if (k == 0) {
return -1;
}
// Our indices start at 0 - while the question demands they begin at 1.
k--;
while (l < 5) { // Only required to go up to k = 10000
end = start * 10;
offset_inner = k - offset;
// How many digits overall in the current block of numbers?
block_length = l * (end - start);
// Update global offset
offset = offset + block_length;
// Is k within these block?
if (k < offset) {
int n = start + offset_inner / l;
int d = offset_inner % l;
return kth_digit_from_end_of_n(n, l - d);
}
l++;
start = end;
}
if (l == 5) {
return -1;
}
return digit;
}
Помощник для поиска определенной цифры в числе ...
static char kth_digit_from_end_of_n(int n, int k) {
char c = '0';
while (k--) {
c = n % 10;
n /= 10;
}
return c + '0';
}
Обратите внимание, что - внутри -алгоритм использует индексы, начинающиеся с 0, в то время как вопрос, с которым вы связываетесь, ожидает индексы, начинающиеся с 1. Следовательно, необходимо уменьшить смещение перед основным циклом while()
:
k--;