给定一个正整数N,统计从1到N的整数中,出现“1”的个数(11这个数算出现两次)

本文介绍了一种高效算法,用于统计从1到给定正整数N中所有数字中1出现的总次数。通过将问题分解为每一位上1出现的次数,利用递归思想实现了快速计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:转换为每位出现1的次数 f(abcde) =  f(a) + f(b) + f(c) + f(d) + f(e)        f(e) = 个位出现1的次数。

先解释几个变量

 iFactor:当前位置的十进制表示,如果当前位为个位,那么iFactor为1,当前位为十位,那么iFactor为10.....

iLowerNumber:比当前位置低的数字,如123,若当前位置为十位(2),那么它的iLowerNumber就是3....

iCurrentNumber:当前位置的数字。

iHigherNumber:比当前位置高的数字,如123,若当前位置为十位(2),那么它的iHigherNumber就是1....

算法:

每个位置出现1的次数又有三种情况:

1.该位置数字为0,    result= iHigherNumber * iFactor;

2.该位置数字为1,    result=iHigherNumber * iFactor + iLowerNumber +1;

3.给位置数字大于1,result= (iHigherNumber + 1) * iFactor;

大家可以自己举例测试上述公式,然后用数学归纳法进行总结,源码如下:

package cn.gt.algori;
/**
 * 给定一个正整数N,统计从1到N的整数中,出现“1”的个数
 * @author gengtao
 * 
 */
public class train0801_2 {

	public static void main(String[] args) {
		long number = 123;
		long start = System.currentTimeMillis();
        System.out.println("总共出现1的个数为:"+Sum1s(number));
        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end-start)+"毫秒");
	}
	
	public static long Sum1s(long number){
		long iFactor = 1; //获取高位的变量
		long iLowerNumber = 0;
		int iCurrentNumber = 0;
		long iHigherNumber = 0;
		long iCount = 0;
		int i = 1;//计数第几位
		while((number / iFactor) != 0){
			iLowerNumber = number - (number / iFactor) * iFactor;
			iCurrentNumber = (int) ((number / iFactor) % 10);
			iHigherNumber = number / (iFactor * 10);
			long temp = 0;
			switch(iCurrentNumber){
			case 0:
				temp = iHigherNumber * iFactor;
				break;
			case 1:
				temp = iHigherNumber * iFactor + iLowerNumber +1;
				break;
			default:
				temp = (iHigherNumber + 1) * iFactor;
				break;
			}
			System.out.println("倒数第 "+i+" 位出现1的个数为:"+temp);
			iCount += temp;
			iFactor *= 10;
			i++;
		}
		return iCount;
	}

}

结果如下:

倒数第 1 位出现1的个数为:13
倒数第 2 位出现1的个数为:20
倒数第 3 位出现1的个数为:24
总共出现1的个数为:57
耗时0毫秒


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值