【题 目】输入一个整数n,求从1到n这n个正数中,1出现的次数。例如:输入12,出现一的数字有1,10,11,12共有5个1,则输出5.

【思 路1】几乎所有的算法题目都有很直观容易想到的方法,当然这类方法的效率通常都不是很好,然而解决问题是第一要义。所以还是从最容易想到的入手。我们可以遍历从1到n的每一个数字k,对于k我们计算出它其中包含的1的个数,方法其实很简单,只需要分别判断个位,十位,百位,千位等的每一位是否为1,然后用计数器记录就OK了。这种思路很简单,我们很容易就可以写出如下的代码:

1 #include

2 #include

3 using namespace std;

4

5 //返回任意一个整数k中包含的1的个数6 int NumbersOf1s(unsigned int k)

7 {

8 int cnt = 0;

9 while(k)

10 {

11 //该位是1,计数器就加1;12 if(k % 10 == 1)

13 cnt++;

14

15 k = k / 10;

16 }

17

18 return cnt;

19 }

20

21 //返回从1到n的n个整数中所包含的1的个数22 int NumbersOf1sFrom1ToN(unsigned int n)

23 {

24 if(n < 0)

25 return 0;

26

27 int count = 0;

28 for(int i = 1;i <= n;i++)

29 {

30 count += NumbersOf1s(i);

31 }

32

33 return count;

34 }

35

36 int main()

37 {

38 cout<<"Please Enter the number N:"<

39 unsigned int number = 0;

40 cin>>number;

41

42 cout<<"The Numbers of 1 From 1 to N is:"<

43 cout<

44

45 return 0;

46 }

运行结果如下:

【思 路2】上述算法的效率不是很好,尤其对于n非常大的情况,这种算法花费的时间很长。其实我们并不需要对于每一个数字计算出它包含的1的个数,我们可以逐位考虑,所有1的个数等于个位上1的个数+十位上1的个数+百位上1的个数+千位上1的个数+。。。接下来的问题,就是如何求解这些位上1的个数?

首先,我们有如下比较容易得到的结论,0-9中1的个数是1个,0-99中十位(10-19)上1的个数是10,0-999中百位上(100-199)上1的个数是100,以此类推。为什么需要这些数字,我们经过简单罗列,很容易发现:个位上1的个数,实际上和这个数字包含多少个10有关,因为对于个位来说,总是从0-9循环,十位上1的个数,实际上和这个数字包含多少个100有关,因为每包含1个100,就有0-99的循环,而0-99中十位上的1是10个;那么关系究竟是什么呢?我们看下面的例子来理解:

对于数字123:

123/10=12,包含12个10,每个10包含1个1(个位1)所以个位共包含12*1=12个1;余数的情况后面单独讨论;

123/100(或者12/10)=1,包含1个100,每个100包含10个1(十位1),所以十位共包含1*10=10个1;余数的情况后面单独讨论;

123/1000(或者1/10)=0,包含0个1000,每个1000包含100个1(百位1),所以百位共包含0*100=0个1;余数的情况后面单独讨论;

现在考虑余数的两种情况:

(1)余数大于1的情况:

数个位时,余数3大于1;所以个位上1的个数要+1;

数十位时,余数2大于1;因为增加了100-120之间(10-19)的数字即110-119,所以十位上1的个数要+10;

(2)余数等于1的情况:

数百位时,余数等于1;我们应该增加100-123这24个数字中百位上的1,共计24个;

在上面的计算中我们发现123/1000=0包含0个1000,所以百位包含0*100个1,这是常规的情况,实际上由于百位为1,从100到n(123)中还应增加:123-100+1个1.

总结上面的情况:就是对于每一位(个位,十位,百位),我们计算他们“通常”情况下(即该数字包含多少个10,100,1000乘以对应的1的个数)包含的1的个数+该位上余数大于1(等于1)的情况下包含的1的个数 = 该位上1的总个数,所有的位遍历,求和,就OK了。根据这种思路我们可以得到如下的代码:

1 #include

2 #include

3 using namespace std;

4

5 int NumbersOf1sFrom1ToN(unsigned int n)

6 {

7 int currentN = n;

8

9 //计数器10 int cnt = 0;

11

12 //商,计算该数字包含多少个10,100,1000等13 int quotient = 0;

14

15 //余数,计算除去“整”的包含,剩下的数字包含的1的个数16 int remainder = 0;

17

18 //每一轮循环中的权重,分别记录10,100,1000中包含多少个位1,十位1,百位1;19 int mult = 1;

20

21 while(currentN)

22 {

23 quotient = currentN / 10;

24 remainder = currentN % 10;

25

26 //包含多少个10,100,1000,乘以对应的数量的个位1,十位1,百位127 cnt += quotient * mult;

28

29 //余数大于1,多加一个该轮下的权重30 if(remainder > 1)

31 {

32 cnt += mult;

33 }

34 //余数等于135 else if(remainder == 1)

36 {

37 cnt += n - currentN * mult + 1;

38 }

39

40

41 currentN = currentN / 10;

42 mult *= 10;

43 }

44

45 return cnt;

46 }

47

48 int main()

49 {

50 cout<<"please enter the number N:"<

51 unsigned int number = 0;

52 cin>>number;

53

54 cout<<"the number of 1s From 1 to N is:"<

55 cout<

56

57 return 0;

58 }

运行结果如下:

References:

注:

1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。

2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。

python从1到n出现了多少个1-【算法21】从1到n的正数中1的出现次数相关推荐

  1. python使用matplotlib可视化线图(line plot)、使用arrow函数在matplotlib可视化图像中添加箭头(drawing arrows in matplotlib)

    python使用matplotlib可视化线图(line plot).使用arrow函数在matplotlib可视化图像中添加箭头(drawing arrows in matplotlib) 目录

  2. python如何统计出现的次数_Python统计日志中每个IP出现次数的方法

    本文实例讲述了Python统计日志中每个IP出现次数的方法.分享给大家供大家参考.具体如下: 这脚本可用于多种日志类型,本人测试MDaemon的all日志文件大小1.23G左右,分析用时2~3分钟 代 ...

  3. python中列表用某个数字出现的次数_Python实现统计给定列表中指定数字出现次数的方法...

    本文实例讲述了Python实现统计给定列表中指定数字出现次数的方法.分享给大家供大家参考,具体如下: 直接看实现: #!usr/bin/env python #encoding:utf-8 ''''' ...

  4. [Python从零到壹] 十四.机器学习之分类算法五万字总结全网首发(决策树、KNN、SVM、分类对比实验)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  5. Python爬虫:爬取知乎上的视频,并把下载链接保存到md文件中

    Python爬虫:爬取知乎上的视频,并把下载链接保存到md文件中 1.需要的Python模块 主要是requests模块,用于得到的网页的数据 安装命令为:pip install requests 2 ...

  6. python统计单词出现次数最多的5个单词_【Python】统计文本中单词的出现次数前十的单词...

    代码: # 读取一个文本,并且统计文本中单词的出现次数 def read_file(): # 在windows环境中的编码问题,指定utf-8 with open('F:/python源码/实验区/0 ...

  7. Python:实现jaccard similarity相似度无平方因子数算法(附完整源码)

    Python:实现jaccard similarity相似度无平方因子数算法 def jaccard_similariy(setA, setB, alternativeUnion=False):if ...

  8. 【爬虫】利用Python爬虫爬取小麦苗itpub博客的所有文章的连接地址并写入Excel中(2)...

    [爬虫]利用Python爬虫爬取小麦苗itpub博客的所有文章的连接地址并写入Excel中(2) 第一篇( http://blog.itpub.net/26736162/viewspace-22865 ...

  9. Python:实现测试信用卡号码有效性credit card validator的算法(附完整源码)

    Python:实现测试信用卡号码有效性credit card validator的算法 def validate_initial_digits(credit_card_number: str) -&g ...

最新文章

  1. 校友管理软件 JAVA_开源项目1:某大学校友管理系统
  2. mysql not exists 效率高_mysql not in、left join、IS NULL、NOT EXISTS 效率问题记录
  3. memcached全面剖析–2. 理解memcached的内存存储
  4. 正在使用的项目,项目名那里出现了红色感叹号?怎么去除?
  5. 2019年系统分析师和系统架构师考试经验
  6. 流程图介绍 以及工具推荐
  7. go语言 mysql时间对比_go时间比较 - Go语言中文网 - Golang中文社区
  8. 【Keil 5】STM32F401CCU6 固件库配置(超详细教程)
  9. 深度残差网络+自适应参数化ReLU激活函数:调参记录17
  10. 弘辽科技:拼多多懵懂商家不知道的直通车操作
  11. Python如何快速爬取淘宝MM呢?教你一招
  12. datav多组件交互
  13. 自媒体运营抖音快手怎么快速涨粉
  14. divi模板下载_适用于任何WordPress主题的Divi Builder插件
  15. 防火墙、WAF、IPS、IDS、堡垒机的区别
  16. U盘数据加密--Bitlocker
  17. 查看dg主备库同步情况
  18. 操作系统常见错误代码总结
  19. 什么是区块链【通俗易懂】
  20. Mann-Whitney检验(曼-惠特尼秩和检验)及matlab代码

热门文章

  1. 学习webpack记录(一)
  2. numpy.transpose()转置失败的问题
  3. list(列表) python
  4. JSTL标签的用法详解
  5. ubuntu 下 SubLime Text2 使用之创建快捷方式
  6. Django 中间件
  7. Nginx.代理MySQL
  8. Vue Router 知识点梳理
  9. Go -- 多个go文件包名都是main
  10. Java程序员常用工具集