数字序列的某一数字
数字按照012345678910111213141516171819…存储,从0开始,第5位为5,第13位为1,第19位为4,求任意位置N对应的数字是多少
解法一:暴力解法,由0开始遍历数字,每个数字拆开,每拆一次位数加1,直至位数等于N,即可可到对应的数字,但是会有重复拆解的情况,效率低下
解法二:寻找序列特征,设立台阶推算出来,0位为0,
一位数为1-9,共9个,占9*1=9位,
两位数为10-99,共9*10=90个,占90*2=180位
三位数为100-999,共9*10*10=900个,占900*3=2700位
四位数为1000-9999,共9*10*10*10=9000个,占9000*4=36000位
…
对于谋位N,查看属于哪个区间[1,9],[10,189],[190,2890]…
找到对应区间,确定位数m,N减第m-1区间的最大值得L,L每m位递增一个数,计算当前递增到第几个数,除10得对应的进位数,取余得到进位的下一位数的第几位,取出对应的数据即可,,,说得不够简练,,,
解法一:
int digitAtIndex_BruteForce(int index)//diy
{
if (index <= 0) return 0;
int Num = 0;
char str[50]="";
int ret = 0;
for (int i = 1;;i++)
{
sprintf(str, "%d", i);
if (strlen(str) + Num >= index)
{
char* pStr = str;
while ((*pStr)!='\0')
{
Num++;
if (Num == index)
{
ret = *pStr-'0';
return ret;
}
else
pStr++;
}
}
else
Num += strlen(str);
}
}
解法二:
int powerOf10(int expo)//diy
{
if (expo == 0) return 1;
int sum = 1;
for (int i = 1; i <= expo; i++)
sum *= 10;
return sum;
}
int digitAtIndex(int index)//diy
{
//int ret1=digitAtIndex_BruteForce(index);
if (index <= 9) return index;
int sumIndex = 9;
int sumPos = 2;
while (true)
{
int tempTotalIndex = 9 * powerOf10(sumPos - 1)*sumPos;
if (sumIndex+tempTotalIndex<index)
{
sumIndex += tempTotalIndex;
sumPos++;
}
else
break;
}
int maxNum = 0;
for (int i = 0; i < sumPos-1;i++)
maxNum += 9 * powerOf10(i);
int finalPos = (index - sumIndex) % sumPos;
int currNum = (index - sumIndex) / sumPos + maxNum;
char tempchar[50];
int ret = 0;
if (finalPos)
{
sprintf(tempchar, "%d", currNum + 1);
ret=tempchar[finalPos-1]-'0';
}
else
{
sprintf(tempchar, "%d", currNum);
ret = tempchar[sumPos-1] - '0';
}
return ret;
}