1. 程式人生 > >給一個正整數n,計算從1-n中出現1的次數

給一個正整數n,計算從1-n中出現1的次數

con 個數字 優化 個數 數字 higher 通過 需要 出現的次數

如12出現1的次數為5,分別是:1,10,11,12

一般做法:從1-n遍歷,計算每一個數中每一位出現1的次數

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非常大時需要大量的計算,運算效率不高。所以需要進行優化。

法二:分析規律 計算每一位出現1的次數

(1)1位數情況

如n=5; 出現1的次數為1

(2)2位數的情況

如n=13

個位上出現1的有:1,11

十位上出現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));

給一個正整數n,計算從1-n中出現1的次數