编程之美--高效率算出1的数目之扩展问题

问题:给定一个十进制数N,写下从1开始,到N的所有二进制数,然后数一下其中出现的所有“1”的个数。

问题分析:

十进制二进制最右边1的个数总和倒数第二1的个数总和 倒数第三1的个数总和倒数第四1的个数总和倒数第五1的个数总和十进制二进制最右边1的个数总和倒数第二1的个数总和倒数第三1的个数总和倒数第四1的个数总和倒数第五1的个数总和
00000000000130110176660
10000110000140111077770
20001011000150111188880
30001122000161000088881
40010022100171000198882
50010132200181001099883
6001103330019100111010884
7001114440020101001010985
80100044410211010111101086
90100154420221011011111187
100101055430231011112121288
110101166440241100012121299
12011006655025110011312121010

 

首先我们看2,4816四个数,2的二进制数总共有21,4的有5个,8的有13个,1633个。而且他们都有一定的规律。比如1624次方,二进制数是10000,在最右边1的个数和倒数第二、第三、第四都是8(即48),最高位是1823次方,二进制数是01000,在最右边1的个数和倒数第二、第三都是434),倒数第四个是1;以此类推42,那么我们可以看出符合这样的公式:

0~2^n的所有二进制数1的总和sum=2^(n-1)*n+1    其中2^n表示2n次方

 

现在我们观察0~24的数的二进制的最右边位的1的个数总和,0,1,1,2,2,3,3,4,4,5,5,6,6...,可以得出这样的公式:

0~n的所有二进制数最右边位的1的个数总和sum:当n%2=0时,sum=n/2; 否则sum=n/2+1

 

观察倒数第二位1的总和。0~10,其他的都是一个常数带上三个相同的常数;比如1,2,2,2,3,4,4,45,6,6,6....  那么设他们的规律是1+3为一组。

我们设sequenceLength=1,repeatLength=3;

这样子我们可以计算出18的二进制数的倒数第二位的1的总和为:看上面表格知道从0开始,那么18就是第19位,看倒数第二1的个数这一列前面是两个0,推出(18+1-2)/(1+3)取整为4,就是说有4组,每组的值其实是两个,那么sum=4*2=8,而(18+1-2)%(1+3)=1;所以sum=4*2+1=9

 

观察倒数第三位1的总和。0~30,其他的都是三个常数带上五个相同的常数;比如1,2,3,4,4,4,4,45,6,7,8,8,8,8,89,10,11,12,12,12,12,12....  那么设他们的规律是3+5为一组。

这样子我们可以计算出18的二进制数的倒数第三位的1的总和为:看上面表格知道从0开始,那么18就是第19位,看倒数第三1的个数这一列前面是四个0,推出(18+1-4)/(3+5)取整为1,就是说有1组,每组的值其实是4个,那么sum=1*4=4,而(18+1-4)%(3+5)=7;就是说18这个数为一组还多七个,由3+5为一组可知,多出来的七个的前三个的值是连续的,后面四个是一样的。那么这多出来的七个数其实就是3+1个值,推出sum=1*4+(3+1)=8

 

观察倒数第四位1的总和。0~70,其他的都是三个常数带上五个相同的常数;比如1,2,3,4,5,6,7,8,8,8,8,8,8,8,8,8....  那么设他们的规律是7+9为一组

这样子我们可以计算出18的二进制数的倒数第四位的1的总和为:看上面表格知道从0开始,那么18就是第19位,看倒数第四1的个数这一列前面是八个0,推出(18+1-8)/(7+9)取整为0,就是说有0组,每组的值其实是8个,那么sum=0*8=0,而(18+1-8)%(7+9)=11;就是说18这个数为零组还多十一个,由7+9为一组可知,多出来的十一个的前七个的值是连续的,后面九个是一样的。那么这多出来的十一个数其实就是7+1个值,推出sum=0*8+(7+1)=8

倒数第二位、倒数第三位。。。倒数第N位的组的规律。

1+33+57+9  可知(1+2^1)+(3+2^1)=3+5;  (3+2^2)+(5+2^2)=7+9......

和面组是前面组的2的幂次方。倒数第二位是2的一次方,倒数第三位是2的两次方...以此类推。

代码分析:

View Code
 1     public class NumberOfOne
 2     {
 3         public long Sum { get; set; }
 4         public void BinaryCount(int n)
 5         {
 6             CountLowest(n);
 7             CountCommont(n);
 8         }
 9 
10         public void CountLowest(int n)
11         {
12             //计算最低位(最右边位)1的总数
13             Sum = (n / 2) * 2 < n ? (n / 2) + 1 : Sum = n / 2;
14         }
15 
16         public void CountCommont(int n)
17         {
18             #region 开始计算除开最低位的1的总数
19             //比如说数列:1,2,3,4,4,4,1,2,3,4,4,4,1,2,3,4,4,4...,那么sequenceLength就是1,2,3的长度3,
20             //repeatLength就是4,4,4的长度(重复次数)3
21             long sequenceLength = 1;
22             long repeatLength = 3;
23             long exponent = 1;
24 
25             for (int i = 0; i < 32; i++)
26             {
27                 // exponent*2表示上面表格的每一列开头有多少个0,成2为幂底的指数增长
28                 long temp = (n + 1) - exponent * 2;
29                 if (temp <= 0)
30                 {
31                     break;
32                 }
33                 if (temp <= sequenceLength)
34                 {
35                     Sum += temp;
36                 }
37                 else
38                 {
39                     //组数
40                     long valueOfDivide = temp / (sequenceLength + repeatLength);
41                     long valueOfMockup = temp % (sequenceLength + repeatLength);
42 
43                     if (valueOfMockup <= sequenceLength)
44                     {
45                         //每组长度是sequenceLength+repeatLength,不过他们只有sequenceLength+1个不同的联系的值,
46                         //比如1,2,3,4,4这组有五个数,不过只有四个不同的连续的值:1,2,3,4。
47                         Sum += valueOfDivide * (sequenceLength + 1) + valueOfMockup;
48                     }
49                     else
50                     {
51                         Sum += valueOfDivide * (sequenceLength + 1) + sequenceLength + 1;
52                     }
53                 }
54                 exponent *= 2;
55                 sequenceLength += exponent;
56                 repeatLength += exponent;
57             }
58             #endregion
59         }
60 }

调用:

View Code
 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             NumberOfOne numberOfOne = new NumberOfOne();
 6             while (true)
 7             {
 8                 int number = int.Parse(Console.ReadLine());
 9                 numberOfOne.BinaryCount(number);
10                 Console.WriteLine("0~{0}的所有二进制数的1的总和为:{1}", number, numberOfOne.Sum);
11 
12                 if (number == 444)
13                 {
14                     break;
15                 }
16             }
17             Console.ReadLine();
18         }
19     }

 

 

转载于:https://www.cnblogs.com/silongxu/archive/2012/12/26/2833539.html

内容概要:该PPT详细介绍了企业架构设计的方法论,涵盖业务架构、数据架构、应用架构和技术架构四大核心模块。首先分析了企业架构现状,包括业务、数据、应用和技术四大架构的内容和关系,明确了企业架构设计的重要性。接着,阐述了新版企业架构总体框架(CSG-EAF 2.0)的形成过程,强调其融合了传统架构设计(TOGAF)和领域驱动设计(DDD)的优势,以适应数字化转型需求。业务架构部分通过梳理企业级和专业级价值流,细化业务能力、流程和对象,确保业务战略的有效落地。数据架构部分则遵循五大原则,确保数据的准确、一致和高效使用。应用架构方面,提出了分层解耦和服务化的设计原则,以提高灵活性和响应速度。最后,技术架构部分围绕技术框架、组件、平台和部署节点进行了详细设计,确保技术架构的稳定性和扩展性。 适合人群:适用于具有一定企业架构设计经验的IT架构师、项目经理和业务分析师,特别是那些希望深入了解如何将企业架构设计与数字化转型相结合的专业人士。 使用场景及目标:①帮助企业和组织梳理业务流程,优化业务能力,实现战略目标;②指导数据管理和应用开发,确保数据的一致性和应用的高效性;③为技术选型和系统部署提供科学依据,确保技术架构的稳定性和扩展性。 阅读建议:此资源内容详尽,涵盖企业架构设计的各个方面。建议读者在学习过程中,结合实际案例进行理解和实践,重点关注各架构模块之间的关联和协同,以便更好地应用于实际工作中。
资 源 简 介 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系, 详 情 说 明 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。 本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系,在此基础上重点分析了一种快速ICA实现算法一FastICA。物质的非线性荧光谱信号可以看成是由多个相互独立的源信号组合成的混合信号,而这些独立的源信号可以看成是光谱的特征信号。为了更好的了解光谱信号的特征,本文利用独立分量分析的思想和方法,提出了利用FastICA算法提取光谱信号的特征的方案,并进行了详细的仿真实验。 此外,我们还进行了进一步的研究,探索了其他可能的ICA应用领域,如音乐信号处理、图像处理以及金融数据分析等。通过在这些领域中的实验和应用,我们发现ICA在提取信号特征、降噪和信号分离等方面具有广泛的潜力和应用前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值