面试题:数字序列中某一位的数字
题目:
数字以0123456789101112131415……的格式序列化到一个字符序列中。
在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等
写一个函数,求任意第n位对应的数字
思路:
先定位到第n位是对应的一个几位数
再定位第n位是对应的这个x位数的哪个数字
再定位是这个数字的第几个位置的数字
1. 定位到第n位是对应的一个几位数
由数字规律可得,0~9有10个数,10~99有90个数,100~999有900个数……——只有0~9为特例,可单独处理,其他r位数,皆有9×pow(10,r-1)个数
因此,对应输入n,如果n<10,直接输出n;
如果n>10,说明指向的数至少为2位数,此时记位数为digit=2,此时的pow(10,digit-1)=loc=10
将1位数的数量减掉,用n-10,再比较n-10与90*2(也就是9*digit*loc)的大小,
两种情况:
如果还需要遍历的数字个数大于180个,说明是至少为3位数——减去2位数的数字个数,将loc=loc*10(因为3位数是以100计),digit=3(表示为三位数),继续减,直到x>9*digit*loc条件不成立,此时的digit为指向的数是几位数
如果小于180个,则说明需要定位的数为2位数
2. 定位第n位是对应的这个x位数的哪个数字
如果此时定位的结果是 digit=3,x=4,loc=100
说明此时在100101102103……这个序列中,第n个数位于第4个位置(从0开始计数),由于是3位数,且序列的开始为loc(每个digit位数的数字开头都为loc),所以定位数字为current = loc + x/digit
3. 定位是这个数字的第几个位置的数字
x%digit表示是数字中的第几位
(代码实现中因为直接用了转字符串方便读取指定位数的值,所以在return的时候-48转为了数字)
代码:
public class Q44 {
public static void main(String[] args) {
String numStr = "";
for(int i=0;i<120;i++) {
String temp = i + "";
numStr = numStr + temp;
}
for(int i=0;i<200;i++) {
System.out.printf("i:%d %c——%d\n",i,numStr.charAt(i),findDigits(i));
}
}
// 是指向第几位的数字
public static int findDigits(int x) {
if(x<10) {
return x;
}else {
x = x-10;
}
int digit = 2;
int loc = 10;
while(x>9*digit*loc) {
x = x-9*digit*loc;
digit ++;
loc *=loc;
}
// 定位第n位是对应的这个x位数的哪个数字
int current = loc + x/digit;
//System.out.printf("digit:%d,loc:%d,x:%d,current:%d\n", digit,loc,x,current);
String re = current+"";
//定位是这个数字的第几个位置的数字
return re.charAt(x%digit)-48;
}
}