1. 程式人生 > >給定一個十進位制正整數N,求出從1開始,到N的所有整數,數字1出現的次數(java實現)

給定一個十進位制正整數N,求出從1開始,到N的所有整數,數字1出現的次數(java實現)

【程式設計之美】給定一個十進位制正整數N,求出從1開始,到N的所有整數,數字1出現的次數。

例如,N=2,則兩個數為1,2 。數字1出現的個數是1.

又如n = 20.則20個數中1出現的為:1,10,11,12,13,14,。。。19 共有12個。

設計一個演算法,可以高效地求出1-N之間出現的1的個數。(主要考慮效率)。

記錄:

 對於一個數abcde。出現1的次數可以通過計算各位中出現的1的個數的和計算出來。以統計10位上1的個數為例,記icurrnum為當前要統計的位(例如10位上)的值(d),ilow為icurrnum低位的值(e),ihighnum為icurrnum高位的值(abc).

則根據icurr的值,出現1的個數可以歸納為:

  i . icurrnum == 0; 則10位上出現1的次數由更高位的abc決定,且次數等於ihighnum * 10;

  ii .icurrnum == 1;則10位上出現1的次數由高位和低位共同決定,次數等於 ihighnum*10  + ilownum+1

  iii icurrnum >1, 則10位上1的次數由高位決定,且次數等於(ihigh+1) *10;

一次計算個位,10位,百位。。。等出現1的個數,相加,就是最終的結果。

import java.util.Scanner;


public class Count1 {
public static void main(String[] args) {
	int n;
	Scanner in =new Scanner(System.in);
	n=in.nextInt();
	int count=0;
	int length=0;
	int m=n;
	while(m>0){
		length++;
		m=m/10;
	}
    for(int i=0;i<length;i++){
    	int mod;
    	if(i==0){
    		mod=1;
    	}else{
    		mod=(int) Math.pow(10, i);
    	}
    	
    	int low=n%mod;
    	int high=n/(mod*10);
    	int pos=(n/mod)%10;
    	if(pos==0){
    		count+=high*(Math.pow(10, i));
    	}else if(pos==1){
    		count+=high*(Math.pow(10, i))+low+1;
    	}else if(pos>1){
    		count+=(high+1)*(Math.pow(10, i));
    	}
    }
    System.out.println(count);
}
}