题目:数字以0123456789101112131415···的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。
书上的思路:
如输入1001
0~9十个数(从第0位开始)显然小于1001,所以从双位数中查找。
10~99,个数为10*9*2=180,显然也小于1001-10=991。
100~999,个数为100*9*3 = 2700,2700大于991-180=811。
所以所求数字处在三位数当中。三位数已100开头,而811 = 3*270+1,因为100本身也占三位所以100+270也正是所求位数对应的数字,即370,余数也就是所求位数所处的索引。即7即为所求数字。
public static int digitAtIndex(int index) {
if(index==0) {
return 0;
}
int digit = 1; // 记录数字当前是几位数
while(true) {
int curCount = getCurCount(digit); // 获取当前数字个数
if(index<curCount) { // 说明在本区间内,进行查找
return getDigit(digit,index);
}else {
index-=curCount;
digit++;
}
}
}
private static int getDigit(int digit, int index) {
int curBeginNumber = getCurBeginNumber(digit); // 获取当前区间开始的首个数,如两位数的首个为10
int curNumber = curBeginNumber+index/digit; // 所求数字处在哪个数字里如第19位处在14这个数字中
int rigthNumber = digit - index%digit; // 从左侧余数转为右侧 ,这里也可以用其他方法找到所需数字
for (int i = 1 ;i< rigthNumber;i++) { // 转为右侧记数后,去除右侧rigthNumber-1位数
curNumber/=10;
}
return curNumber%10; // 到这一步其实像370这个数字已近变为37,只需对个位取余就找到目标数字了
}
/**
*
* 获取当前数字个数
* @param digit
* @return
*/
private static int getCurBeginNumber(int digit) {
if(digit==1) {
return 0;
}
return (int) Math.pow(10,digit-1);
}
/**
* 获取当前数字个数,如0~9为十个,从0位开始到第0位
* @param digit
* @return
*/
private static int getCurCount(int digit) {
if(digit==1) {
return 10;
}
return (int) (9* Math.pow(10, digit - 1)*digit);
}