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

第2章 数字之魅——数字中的技巧

时间:2015-03-18 20:00:16      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

2.1求二进制中1的个数

法1:整型数观念。

二进制中1在数中的体现,也就是当一个数是奇数时最末位就是1。那么我们可以将一个数判断是否是奇数。如果是就统计加1。并且/2 失去这一位。

技术分享
int count;
count = 0;
void Count(int num)
{
    while(num)
    {
        if(num %2 ==1)
        {
            count ++;
        }
        num /= 2;
    }
}
法1

法2:从二进制的角度。

利用位运算。从二进制的角度对数进行1的统计。

熟悉位运算的用法。暂时介绍 & 按位与 和 >> << 。对于<< >>不过多介绍,就是位的前进的后退。可以理解: >>n 是 /pow(2,n)。 <<n 是 *pow(2,n)。

& 是位之间的运算。

实质上是: 1&0=0 0&0=0 1&1=1

运算举例:1010&1110=1000

有一种用法是取某位。如果取第一位也就是0000001也就是1。

技术分享
int count;
count = 0;
void Count(int num)
{
    while(num)
    {
        count += (num&1);//位运算的优先级是很慢的。
        num >>= 1; 
    }
}
法2

法3:利用&的特殊用法。算法时间复杂度根据1的个数的线性时间。

对于&我们不是说了它有一种用处是取位吗?那我们是否可以

num&?=直接可以删除掉最后一位的1呢?答案当然是有的。我们利用逆向思维。来观察这个?满足什么样的特点。这是十分常用的思想方法。

1010&X=1000 X = 1?0?(式子里的问号的意思是可以0也可以是1)

1100&X=1000 X = 10??

1110&X=1100 X = 110? 

假若第一个式子1?0? 第二个?假若是0。我们可以发现一个关系。X和num本身的关系。只要num最后的1那一位变成0。前1前面位的数都保留不变。而1后面的由于num的1后面都是0。而满足这种关系的。只要num-1。因为num最后一位后面的数都是0。(当然1也可以是最后一位)。

举例:1100 - 1 = 1001。1110-1 = 1101。1010-1 = 1001。

技术分享
int count;
count = 0;
void Count(int num)
{
    while(num)
    {
        num = num&(num-1);
        count ++ ;
    }
}
法3

在本章节,还使用了查表法。(分支操作不讲)。也就是打表。因为byte只有8位 2^8 = 256个状态。完全可以打表。简单hash。所以对于状态数量一定且可以实现的时候完全可以考虑这方面。来用空间换时间。以及这里有位运算的学习。还有逆向思维。和不同角度来观察一个数。另外主要是记录学习编程之美给我带来的思维上的跃进。

根据后文网址http://blog.csdn.net/justpub/article/details/2292823的算法时间分析。打表法并没有想象中那么快。而且同时这提醒了我解法一也不过8次的循环。但我想我们也得考虑一下程序的适用性。

第2章 数字之魅——数字中的技巧

标签:

原文地址:http://www.cnblogs.com/Milkor/p/4347868.html

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