码迷,mamicode.com
首页 > 其他好文 > 详细

2.4 1的数目

时间:2020-11-23 12:47:11      阅读:19      评论:0      收藏:0      [点我收藏+]

标签:bre   最大的   多少   return   最大   display   情况   string   tor   

2.4 1的数目

基础问题

写一个函数\(f(N)\), 返回1到N之间出现的1的个数,比如\(f(12) = 5\)

解法

  • 解法1 暴力求解 直接遍历即可
  • 解法2 通过分析小于n的数在每一位上可能出现1的次数之和
// 2.4 1的数目
class Test{
	public static void main(String[] args) {
		/**
		基础问题:给一个十进制的正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有1的个数
		1 写一个函数$f(N)$, 返回1到N之间出现的1的个数,比如$f(12) = 5$
		2 满足条件$f(N) = N$的最大的N是多少?
		*/

		System.out.println(calcNumOfOne(120));
		// for(int i = 0;i<120;i++) System.out.println(calcNumOfOne2(i));
	}
	/** 基础问题1
		解法1 暴力求解 直接遍历即可
	*/  
	public static int calcNumOfOne(int n){
		int res = 0;
		for(int i = 0;i<=n;i++){
			int j = i;
			while(j !=0){
				if(j%10 == 1) res++;
				j/=10;
			}
		}
		return res;
	}
	/** 基础问题
		解法2 
		通过分析小于n的数在每一位上可能出现1的次数之和
		分析过程:
			先看只有1位数字的情况,只有1才会出现1个1
				$$if 0 < N < 10 , f(N) = 1 $$
			再看2位数的情况
				1出现的次数等于个位出现1的个数+十位出现1的个数
					13 = 2 (1,11) + 4 (10,11,12,13) = 6
					23 = 3(1,11,21) + 10(10,11,12,13,14,15,16,17,18,19)= 13
					33 = 4(1,11,21,31)+ 10(10,11,12,13,14,15,16,17,18,19)= 14
					....
					93 = 10 (1,11,21,31,41,51,61,71,81,91)+ 10(10,11,12,13,14,15,16,17,18,19) = 20
			再看3位数的情况:
				1出现的次数 = 个位上出现1的次数+十位上出现1的个数+百位上出现1的个数
					n =123
						个位上出现1的个数:13 (1,11,21,31,41,51,61,71,81,91,101,111,121)
						十位上出现1的个数:20(10~19,110~119)
						百位上出现1的个数:24(100~123)
			分析:
			假设N=abcde
				如果百位上的数字是0,那么百位上出现1的次数由高位决定 b*100
				如果百位上的数字是1,那么百位上出现1的次数由低位与高位共同决定 b*100 + de+1
				如果百位上的数字>1,那么百位上出现1的次数由高位决定 (b+1)*100
	*/
	public static int calcNumOfOne2(int n){
		int res = 0;
		// 表示现在遍历到哪一位
		int iFactor = 1;
		// 表示比当前小的位数的数字
		int iLowerNum = 0;
		// 表示当前位的数字
		int iCurrNum = 0;
		// 表示比当前大的位数的数字
		int iHighNum = 0;
		while(n/iFactor != 0){
			iLowerNum = n - (n/iFactor) * iFactor;
			iCurrNum = (n/iFactor)%10;
			iHighNum = n/(iFactor*10);
			switch(iCurrNum){
				case 0:
					res+=iHighNum * iFactor;
					break;
				case 1:
					res+=iHighNum * iFactor + iLowerNum + 1;
					break;
				default:
					res+=(iHighNum+1)*iFactor;
					break;
			}
			iFactor*=10;
		}
		if(res == n) System.out.print(res +" .. ");

		return res;
	}

}

基础问题2:满足条件\(f(N) = N\)的最大的N是多少?

\[N = N^{11} - 1 \]

满足条件\(f(N) = N\)的最大的N是多少?

拓展问题

对于二进制而言:每一位出现1的次数 = \(high * 2^{i-1} + num_i + low\)

每一位出现1的次数=高位乘以上面的因子 + 该位的数字(1/0)+低位的数字(1/0)


// 2.4 1的数目
class Test{
	public static void main(String[] args) {
		// 101
		// 0*2^0 + 1 + 0 + 1*2^0 + 0 +1 + 0*2^1 + 1 + 0 = 1 + 1 + 1 + 1 = 4
		System.out.println(calcNumOfOne3(12));

		
	}
	/**
	拓展问题:
	对于二进制而言:每一位出现1的次数 = $high * 2^{i-1} + num_i + low$
	每一位出现1的次数=高位乘以上面的因子 + 该位的数字(1/0)+低位的数字(1/0) 

	*/

	public static String calcNumOfOne3(int n){
		int res = 0;
		// 表示现在遍历到哪一位
		int iFactor = 1;
		// 表示比当前小的位数的数字
		int iLowerNum = 0;
		// 表示当前位的数字
		int iCurrNum = 0;
		// 表示比当前大的位数的数字
		int iHighNum = 0;
		while(n/iFactor != 0){
			iLowerNum = n - (n/iFactor) * iFactor;
			iCurrNum = (n/iFactor)%10;
			iHighNum = n/(iFactor*10);
			switch(iCurrNum){
				case 0:
					res+=iHighNum * iFactor;
					break;
				case 1:
					res+=iHighNum * iFactor + iLowerNum + 1;
					break;
				default:
					res+=(iHighNum+1)*iFactor;
					break;
			}
			iFactor*=10;
		}
		String s = Integer.toBinaryString(res);
		return s;
	}
}

2.4 1的数目

标签:bre   最大的   多少   return   最大   display   情况   string   tor   

原文地址:https://www.cnblogs.com/botak/p/14005748.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!