统计数字问题

统计数字问题,见李晓东《计算机算法设计与分析》1-1。

题意为。给定一个数N求从1到N的这N个数中0,1,2,3,4,5,6,7,8,9这10个数字出现的次数:

同时所有的数字没有前导的0。 如6要写成6而不是 006 ,06这种形式。  

举例子: 数字 1011 代表1出现3次 0出现1次。。

《编程之美》上也有求1的个数。不过1比较特殊。李的题是求所有的数字出现的次数

分析如下:

这个分析同《编程之美》但是要扩展下:

我们分别统计在每一个位上数字出现的次数:

假如这个数是 1245

1.我们首先统计 1在 十位上出现的次数 = (12+1)*10 这个很容易能够得出来(分别是 120* 110* 100* .... 000*)注意这里我们算的时候将前导0算在0的记数中,算法最后会去除。

2.如果统计4在十位上出现的次数 = (12)*10 + 5 +1。在这里4就是原来数在十位上的数,此是4并没有通过进位到达5所以它的个数不仅与高位有关也和地位有关。

3。 统计 5在十位上出现的次数 =  (12)*10 由于5大于在十位上的数,125*不可能出现在原来的数中,所以这里的个数仅和高位有关系。即(11. 10.09.到00);

通过以上几条规律可以推测得到各位上数字上出现的次数。但是0的个数不准确,因为我们将前导0也算入进来了。那前导0的个数有多少个呢?

如果N是三位数。那么有如下规律:

000 

001

....(9)

009

010

....(90)

099

100

....(900)

999

省略 号右面代表个数。

这个规律很明显,前导0的个数和N的位数有关系。。计算很简单就可以实现。

综合以上规律得到代码如下:

void  count_num( int  a)
{
    
int  count[ 10 =  { 0 };
    
int  n  =   1 ;
    
int  zero  =   0 ;
    
int  weishu  =   0 ;
    
while (a / n)
    {
        weishu
++ ;
        
int  lowp  =  a  -  (a / n) * n;
        
int  curr  =  (a / (n)) % 10 ;
        
int  highp  =  a / (n * 10 );
        
for  ( int  i  =   0 ;i < 10 ;i ++ )
        {
            
if  (i < curr)
            {
                count[i] 
+=  (highp + 1 ) * n;
            }
            
else   if  (i  ==  curr)
            {
                count[i] 
+=  (highp) * n;
                count[i] 
+=  (lowp + 1 );

            }
            
else
            {
                count[i] 
+=  (highp) * n;
            }
        }
        n 
=  n * 10 ;
    }
    
int  t  =   1 ;
    
while (t <= weishu)
    {
        n 
=  n / 10  ;
        zero 
+=  t * (n - 1   - n / 10   + 1 );
        t
++ ;
    }
    count[
0 =  count[ 0 - zero;
    
for  ( int  i  =   0 ;i  < 10 ;i ++ )
    {
        cout
<< i << "   " << count[i] << endl;
    }
    
}

 

 

 

转载于:https://www.cnblogs.com/davidluo/articles/1815310.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值