给一个正整数n,计算从1-n中出现1的次数

如12出现1的次数为5,分别是:1,10,11,12优化

通常作法:从1-n遍历,计算每个数中每一位出现1的次数spa

function count(num){    
    var n=0;
    for(var i=1;i<=num;i++){
        n+=Number(i);
    }
    console.log(n);
}
function Number(i){
    var number=0;
    while(i!=0){
        if(i%10==1){
            number+=1;
        }
        i=parseInt(i/10);
    }
    return number;
}
var num=1234;
count(num);

这种作法对每个数字都要作除法和求余运算,以求出该数字中1出现的次数。可是当输入的n很是大时须要大量的计算,运算效率不高。因此须要进行优化。code

 

法二:分析规律  计算每一位出现1的次数blog

(1)1位数状况it

如n=5;  出现1的次数为1io

(2)2位数的状况console

如n=13function

个位上出现1的有:1,11class

十位上出现1的有:10,11,12,13效率

f(n)=2+4=6;

如n=23

个位出现1的有:1,11,21

十位出现1的有:10,11,12,13,14,15,16,17,18,19

f(n)=3+10=13

经过对两位数进行分析,咱们发现:

个位出现1的次数不只和个位数字有关,还和十位数字有关;若是n的个位数大于等于1,则个位出现1的次数为十位数字加1;

若是个位数字为0,则个位出现1的次数等于十位的数字;

而十位出现1的次数不只和十位数有关,还和个位数有关;若是十位数等于1,则十位数出现1的次数为个位数的数字加1,若是十位数大于1,则十位数出现1的次数为10;

(3)3位数的状况

如n=123;

个位出现1的次数13:1,11,21,。。。91,101,111,121 

十位出现1的次数20:10-19,110-119

百位出现1的次数24:100-123

f(n)=13+20+24

 

若是要计算百位上出现1的次数,它受三方面影响:百位上的数字,百位如下的数字以及百位以上的数字

若是百位上数字为0,百位上可能出现1的次数由更高位决定。好比:12013,则能够知道百位出现1的状况多是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。能够看出是由更高位数字(12)决定,而且等于更高位数字(12)乘以 当前位数(100)。

若是百位上数字为1,百位上可能出现1的次数不只受更高位影响还受低位影响。好比:12113,则能够知道百位受高位影响出现的状况是:100~199,1100~1199,2100~2199,,.........,11100~11199,一共1200个。和上面状况同样,而且等于更高位数字(12)乘以 当前位数(100)。但同时它还受低位影响,百位出现1的状况是:12100~12113,一共114个,等于低位数字(113)+1。

若是百位上数字大于1(2~9),则百位上出现1的状况仅由更高位决定,好比12213,则百位出现1的状况是:100~199,1100~1199,2100~2199,...........,11100~11199,12100~12199,一共有1300个,而且等于更高位数字+1(12+1)乘以当前位数(100)。

function num1(n){
    var count=0;//个数
    var curBit=1;//当前位
    var lowerNum=0;//低位数字
    var curNum=0;//当前位数字
    var higherNum=0;//高位数字
                
    if(n<=0){
        return 0;
    }
    while(parseInt(n/curBit)!=0){
        lowerNum=n-parseInt(parseInt((n/curBit))*curBit);
        curNum=parseInt((n/curBit)%10);
        higherNum=parseInt(n/(curBit*10));
                    
        //若是当前位为0,出现1的次数由高位决定
        if(curNum==0){
            //等于高位数字乘当前位数
            count+=higherNum*curBit;
        }
        //若是当前位为1,出现1的次数由高位和低位决定
        else if(curNum==1){
            //等于高位数字*当前位数+低位数字+1
            count+=higherNum*curBit+lowerNum+1;
        }
        //若是大于1,出现1的次数由高位决定
        else{
            //(高位数字+1)*当前位数
            count+=(higherNum+1)*curBit;
        }
                    
        //位数向前移一位
        curBit*=10;
    }
    return count;
}
console.log(num1(1234));
相关文章
相关标签/搜索