剑指offer44. 数字序列中某一位的数字 P225
题目:数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数find求任意位对应的数字。
// 跳过前边的无用位,只在有用的位数上操作
int powDigital(int bits){ // 统计bits位的数一共有几个(bits=2,ans不是100,是90!)
if (bits == 1) return 10;
else return (int)pow(10, bits - 1) * 9; // 不要用pow,精度可能损失,自己累乘
}
// 统计第bits位开始的第一个数,1是0,2是10,3是100,4是1000……
int beginOfNumbersOnBits(int bits) { // 不要用pow,精度可能损失,自己累乘
if(bits == 1)
return 0;
int sum = 1;
for(int i = 1; i < bits; ++i)
sum *= 10;
return sum;
}
int findCore(int index, int bits) { // 811= 270*3(bits)+1
int number = beginOfNumbersOnBits(bits) + index / bits; // 370,(第369个数)
int mod = index % bits; // 370这个数的第1位
for (int i = 1; i < bits - mod; ++i) // 把370后面的几位消掉
number /= 10;
return number % 10; // 最后得到37,取个位mod
}
int find(int index) { // 主调函数,输入1001
if (index < 0) return -1;
if (index < 10) return index;
int bits = 1; // 此时到达的位数
while (1) {
if (index < bits * powDigital(bits)) { // 811 < 3* 900 (900个3位数,一共2700位)
return findCore(index, bits);
}
else {
index -= bits * powDigital(bits); // 把前边不必要的减掉 1001-10-180=811
++bits; // 同时位数递增
}
}
}