计算 1 至 n 中数字 X 出现的次数

描述:计算 1 至 n 中数字 X 出现的次数,其中 n1,X[0,



n1,X[0,9]


n1,X[0,9]
n1,X[0,9]

1.1 考虑x范围为1~9:

首先要总结不同位置情况下,X出现的个数:

1.  从1至10,X在个位出现1次

2. 从1至100,X在十位出现10次

3. 从1 至1000,X在百位出现100次

...……

结论:从1至10^i, X在第i位出现10^(i-1)次  //(i为从右至左)

而当计算第i位包含x的个数时,还需分别考虑第i位大于、小于、等于x时的情况,故总结如下:

1. 取所有不低于第i位的数字,乘以10^(i-1),得到基值a

2. 取第i位数字,计算修正值:

1)若大于x,结果为 a+10^(i-1)

2)  若等于x,取低于第i位数字b,结果为 a + b + 1

3)若小于x,结果为 a

故当X不为0时,代码如下:

class Solution {
public:
    int NumberOfxBetween1AndN_Solution(int n, int x)
    {
        int sum = 0, k;       
        for(int i=1; k = n / i; i *= 10)
        {
            sum += k / 10 * i;
            int cur = k % 10;
            if(cur > x)  sum += i;
            else if(cur == x)  sum += n - k * i + 1;
        }        
    return sum;
    }
};

1.2 单独考虑 x = 0

x = 0 时与上述情况的区别是:

1. 从个位累加到次高位就应结束(最高位不会包括零)

2. 第i位的基础值为高位数字乘以 10^(i-1) - 1(从1~10,数字0在个位出现0次)

当x等于0时,代码如下:

class Solution {
public:
    int NumberOfxBetween1AndN_Solution(int n, int x)
    {
        int sum = 0, k;       
        for(int i=1; (k = n / i) / 10; i *= 10)
        {
            sum += (k / 10 - 1) * i;
            int cur = k % 10;
            if (cur > x)  sum += i;
            else if (cur == x)  sum += n - k * i + 1;
        }        
    return sum;
    }
};

可化简为:

class Solution {
public:
    int NumberOfxBetween1AndN_Solution(int n)
    {
        int sum = 0, k;       
        for(int i=1; (k = n/i) / 10; i *= 10)
        {
            sum += k / 10 * i ;
            if( k % 10 == 0)  sum += n - k * i + 1 - i;
        }        
    return sum;
    }
};

综上,将两种情况合并,代码如下:

class Solution {
public:
    int NumberOfxBetween1AndN_Solution(int n, int x)
    {
        int sum = 0, k;       
        for(int i=1; k = n / i; i *= 10)
        {
            int high = k / 10 ;
            int low = k % 10;

    if(x==0) {

if(high) high--;

else break;

}

            sum += high * i;    

    if(low > x)  sum += i;
            else if(cur == x )  sum += n - k * i + 1;

        }        
    return sum;
    }
};


参考文章:http://www.cnblogs.com/cyjb/p/digitOccurrenceInRegion.html

猜你喜欢

转载自blog.csdn.net/qq_24153697/article/details/79094622