给定一个十进制正整数N,求出从1开始到N的所有整数中,“1”出现的个数。
如:
N = 13 ,那么1,2,3,4,5,6,7……,10,11,12,13中“1”出现的个数为 6
解法一:
这个问题看上去并不困难,可以想到的就是 从1 开始遍历到N,将其中每一个数中含有的“1”相加起来,自然就得到了从1 到 N 所有“1”的个数和。
代码清单:
/* * 判断一个整数中出现1 的次数 * 用%运算,依次判断个位、十位、百位…上的数字是否为1 */ public static int count1InAInteger(int n) { int count1 = 0; while (n != 0) { count1 += (n % 10 == 1) ? 1 : 0; n /= 10; } return count1; } /* * for 遍历1 到 整数N, * 将所有整数中出现"1" 的次数累加 */ public static int fun(int N) { int count = 0; for (int i = 0; i <= N; i++) { count += count1InAInteger(i); } return count; }
该方法很容易理解,实现也比较容易,最致命的问题是效率。如果N很大,则需要很长的时间才能得出计算结果。测试了一下,如果 N= 100 000 000,大约需要40秒
解法二:
想要提高效率,必须摒弃解法一中的遍历算法。能不能分析正整数每一位上“1”出现的次数,来解决问题呢?
假设N= abcdef ,这里 a,b,c,d,e,f 分别是N各个数位上的数字。如果现在要计算百位d 上出现“1”的次数,它将会受到三个因素的影响:百位上的数字,百位以下的数字(低位),百位以上的数字(更高位)。
<!--[if !supportLists]-->1、<!--[endif]-->如果百位上的数字为0,可知,百位上出现“1”的次数由更高位决定。比如12013,百位上出现“1”的情况是 100~199,1100~11991,2100~2199,……,11100~11199,一共有1200个,也就是说由更高位数字(12)决定,并且等于更高位(12)* 当前位数(100)= 1200
<!--[if !supportLists]-->2、<!--[endif]-->如果百位上的数字为1,百位上出现“1”的次数不仅受高位影响,还受低位的影响,比如12113,我们已经知道受高位影响出现“1”的次数为1200,受低位影响会出现“1”的数字 12100~12113 ,有13个
<!--[if !supportLists]-->3、<!--[endif]-->如果百位上的数字大于1,则百位上出现“1”的次数仅由更高位决定。比如12213,百位上出现“1”的情况是:100~199,1100~11991,2100~2199,……,11100~11199,12100~12199,一共1300个,[更高位(12)+1]*当前位数(100)
public static int fun2(int N) { int count = 0; // 记录次数 int iFactor = 1; // 当前位数 int iLowerNum = 0; // 低位 int iCurrNum = 0; // 当前位上的数字 int iHigherNum = 0; // 更高位 while (N / iFactor != 0) { iLowerNum = N - (N / iFactor) * iFactor; iCurrNum = (N / iFactor) % 10; iHigherNum = N / (iFactor * 10); switch (iCurrNum) { case 0: count += iHigherNum * iFactor; break; case 1: count += iHigherNum * iFactor + iLowerNum + 1; break; default: count += (iHigherNum + 1) * iFactor; break; } iFactor *= 10; } return count; }
该解法同样计算N = 100 000 000,只需要不到1毫秒的时间,相对于第一种效率至少提高了40 000 倍。
相关推荐
- 设置循环次数和乘法因子,准备进行ASCII码到十进制数的转换。 - 循环读取`BUF`中的ASCII码,减去 `'0'` 的ASCII码值(30H),从而获取实际的十进制数值。 - 使用乘法和加法运算,将每一位十进制数转换为二进制...
在本案例中,我们讨论的是一个使用Matlab实现的十进制遗传算法。Matlab作为一种强大的数值计算和编程环境,非常适合进行这种复杂算法的开发。 首先,我们要理解遗传算法的基本流程。它通常包括以下步骤: 1. **...
通过`AND AL, 1`和`ADD BL, AL`判断当前位是否为1,并将其加到BX中,完成一次二进制位到十进制值的转换。 5. **重复以上步骤直到所有二进制位被处理完毕**。 #### 十进制输出 一旦所有二进制位被转换,程序进入...
1. **十进制数与字符串的转换**: 当我们需要计算数字中"1"的个数时,首先要将数字转换为字符串形式,因为只有在字符串中我们才能逐字符地检查并计数。C语言中没有内置的整数到字符串的直接转换函数,通常我们会用`...
在数字电子设计领域,十进制计数器和七段译码器是两个重要的组成部分,它们在硬件描述语言(如VHDL)中被广泛使用,以实现数字系统的计数和显示功能。在这个项目中,我们将探讨如何用VHDL来实现这两种组件,并将它们...
### 十进制数相乘并显示乘积 本文将详细介绍如何通过汇编语言实现一个多位十进制数与一个单个十进制数相乘,并将结果以十进制形式显示在屏幕上的过程。本示例代码适用于早期的DOS环境。 #### 1. 代码结构与初始化 ...
本项目旨在设计一个8位十进制的数字频率计,能够测量0到1MHz范围内的信号频率。通过该项目的学习和实践,学生将能够深入了解频率计的工作原理,掌握数字系统设计的基本方法,并提高实际操作能力。 #### 二、设计...
综上所述,这段汇编语言程序主要实现了将两个多位十进制数相加,并将结果显示在屏幕上的功能。通过以上分析,我们不仅了解了汇编语言的基本语法和指令集,还掌握了如何使用汇编语言进行简单的算术运算和输入/输出...
在本案例中,十进制编码被用来表示30维变量的解决方案,每个变量都是一个实数,这使得直接处理浮点数变得更加方便,避免了二进制到十进制的转换步骤。 **MATLAB中的遗传算法工具箱** MATLAB7.0提供了一个强大的...
### 汇编语言程序分析:从键盘接收十进制数字并转换为十六进制显示 #### 程序概述 本程序通过汇编语言实现了一个功能:它可以从键盘接收用户输入的最多10个十进制数字(遇到回车键停止),然后将这些数字转换成BCD...
在这个实验中,我们关注的是两个重要的概念:括号配对和十进制转十六进制。这两个主题是计算机科学中的基础知识,尤其是在编译原理、数据处理和算法设计中扮演着关键角色。 首先,让我们深入了解一下括号配对。括号...
输入一个整数 n,求从 1 到 n 这 n 个整数的十进制表示中 1 出现的次数。 例如输入 12,从 1 到 12 这些整数中包含 1 的数字有 1, 10, 1 1 和 12, 1 一共出现了 5 次 代码实现(GCC编译通过): #include stdio...
十进制调整指令PPT学习教案 在本学习教案中,我们将学习十进制调整指令的使用和实现。在80X86微处理器上,十进制调整指令是实现BCD(Binary Coded Decimal)运算的重要组成部分。 DAA指令 DAA(Decimal Adjust ...
在C语言中,将十进制数转换为二进制并计算其中1的个数是一项基本操作,这对于理解计算机底层工作原理以及进行位运算时非常有用。以下是一个简单的C语言程序,它实现了这个功能: 首先,我们需要包含头文件,以便...
这个压缩包文件包含了一个C++实现的BP神经网络,用于识别二进制数和十进制数。以下是关于BP神经网络及其C++实现的详细知识: 1. **BP神经网络基本原理**: - BP神经网络由输入层、隐藏层和输出层组成,其中隐藏层...
- 十进制转格雷码:首先将十进制数转换为二进制,然后按照二进制转格雷码的方法转换。 - 格雷码转十进制:先将格雷码转为二进制,再将二进制数转为十进制。 5. `graycodesolution.cpp` 和 `graycodesolution.h` ...
例如,如果二进制字符串为“1011”,对应的十进制数就是1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 11。这种转化是将算法中的计算结果与实际问题联系起来的关键步骤。 然后,我们关注“交叉”操作。在遗传算法中,交叉...
支持十进制运算,二进制运算.zip"文件中,我们可以预见到这可能是一个关于大数运算的程序或库,它不仅支持常见的十进制运算,还特别强调了二进制运算。 1. **大数运算**:大数运算通常在需要精确计算或处理大数据量...
在VB(Visual Basic)编程中,转换十进制数到二进制数是常见的操作,这对于理解计算机底层工作原理和进行位操作至关重要。本程序通过三种不同的方法来实现这一功能:Do循环、For循环以及递归算法。接下来,我们将...