【剑指offer】面试题44:数字序列中某一位的数字【C++版本】

20180609

题目:

数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数,求任意第n位对应的数字。

解题思路:

1.从位数为1开始统计不同的位数的数字所占的总位数,如0~9一共占10位,10~99一共占180位…并进行累加,一旦累加的和超过给定的位数,可以找到目标数字的一个大概范围,再进一步进行分析。

例子:

比如找,查找序列的第1001位是什么数字?
1.序列的前10位是0~9这10个数字,没有查过要查找的位数1001
2.然后是两位的数字10~99一共占180位,累加190位也没有超过1001
3.三位的数字100~999一共占2700位,累加起来2890超过了1001,所以1001位所在的数字是一个三位数。
4.已知三位数之前的数字总共占去190位,所以要查找的是三位数字中的第(1001-190)=811位
5.811/3 = 270(余1),所以找的是100+270-1 = 369后面的数字的第二位(这里要注意,从0开始计数),即370的第二位即7

代码【C++版本】

#include <vector>                      
#include <string>
#include <iostream>
#include <math.h>

using namespace std;

//取得位数为index的数开头的第一个数
int getFst(int index)
{
    if(index == 1)return 0;

    return static_cast<int>(pow(10,index-1));
}

//最后取得指定位上的数字
int getTheNum(int num,int posi,int index)
{
    int n = index - posi - 1;

    for(int i = 0;i < n;i++){
        num = num/10;
    }

    return num%10;
}

//位数为n的数一共有多少个
int cntOfIntegers(int n)
{
    if(n == 1)return 10;

    int resu = 1;
    for(int i = 1;i != n;i++){
        resu *= 10;
    }

    return 9*resu;
}

int numOnPosiN(int n)
{
    //输入出错的情况
    if(n < 0)return -1;

    int index = 1;
    while(true){
        //cnt为位数为index的数一共所占的位数
        int cnt = cntOfIntegers(index)*index;
        if(n - cnt  < 0){
            //
            int fst = getFst(index);
            int pre = n/index;
            int remain = n%index;

            return getTheNum(fst+pre,remain,index);
        }

        n -= cnt;
        index++;
    }

    //如果循环完毕还没有返回,说明出错返回-1
    return -1;
}

int main()
{
    cout << "Please enter a interger:" << endl;
    int n;
    while(cin >> n){
        cout << numOnPosiN(n) << endl;
    }

    return 0;
}  

猜你喜欢

转载自blog.csdn.net/m0_37950361/article/details/80633177