題目:數字以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);
}