有40亿个整数,再给一个新的整数,需要判断新的整数是否在1亿个整数中。

此处需要用到bitmap方法,每个整数用一个bit表示,1表示存在,0表示不存在。因此一个4字节的int=32个bit也就是可以表示32个数字,那么1亿个数字需要 100000000/32个int型。也就是需要申请100000000/32个字节的数组。需要耗费25M的内存。

这种方法也降低了数组需要的内存。

申请数组,N代表多少个数字,WORD代表一个int字节能表示多少位数字

#define WORD 32

#define SHIFT 5

#define MASK 0x1f

#define N 100000000

int bitmap[1 + N / WORD];

整型数组全部初始化为0.

void init_bitmap()

{

int size;

size = 1 + N / WORD;

memset(bitmap, 0, size);

}

将数字对应的Bit置为1。对于号码 89256,由于89256 mod 32=2789…8,这样我们应该置a[2789]中32位字符串的第8位(从低位数起)为1。SHIFT在这里表示右移的个数,i>>SHIFT就等于89256 mod 32=2789. MASK也就是16进制的31. i & MASK就等于i/32(求余操作)

void set(i)

{

bitmap[i >> SHIFT] |= (1<< (i & MASK));

}

判断是否存在,和前面用到的方法一样,不同的是这里运用的是与运算

int Judge_exist(i)

{

return bitmap[i >> SHIFT] & (1 << (i & MASK));

}

将对应的数代表的bit位清零

void clear(i)

{

bitmap[i >> SHIFT] &= ~(1 << (i & MASK));

}

二:

在不创建临时变量的情况下进行交换两个数。既然不能创建临时变量,那么就需要采取异或运算

对bit进行异或运算。

1 a^=b 将a和b bit中不一样的点位提取出来存入a

2 b^=a 将b中和a中不一样的点位取反,也就实现了b=a

3 a^=b 将a中和b不一样的点位取反,也就实现了a=b

例如a=3:0011 b=7:0111

a^=b  a=0100

b^=a  b=0011=3

a^=b  a=0111=7

代码实现

void swap_without_temp(int *a, int *b)

{

(*a) ^= (*b);

(*b) ^= (*a);

(*a) ^= (*b);

}

三:

不进行移位操作判断数字的bit有多少个1

代码如下:

int count_bit_1(int a)

{

int count = 0;

while (a > 0)

{

count++;

a = a & a - 1;

}

return count;

}

n-1发生了什么

(1)     二进制数n,n-1后,如果最后一位是0,将向前一位借2,2-1=1。最后一位为1。如果前一位为0,将继续向前一位借2,加上本身少掉的1.则变为1。一直遇到1。减为0.

所以 二进制 xxxx10000-1 = xxxx01111

(2)     n&n-1

按照上述 n=xxxx10000,n-1=xxxx01111

xxxx10000

xxxx01111

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。

找出那个只出现了一次的元素。 相同的值进行异或等于0,如果其余元素都出现两次,而只有一个元素出现一次,那么把数组中所有的

元素都进行异或运算

int findOnce(int arr[], int size)

{

int i;

int result;

result = 0;

for (i = 0; i < size; i++)

{

result ^= arr[i];

}

return result;

}

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。找出只出现一次的那两个元素。

1 首先将所有元素进行异或运算,得到的结果是仅出现一次的两个元素异或值

2 采用differ &= -differ 得到只出现在其中一个元素中的1个点位

3 用该点位去和数组中的元素做与运算。这个点位存在的所有数在一起做异或,这个点位不存在的所有数一起做异或

这样就可以将区分的做异或运算从而分别得到两个值

void findOnce_update(int arr[], int size,int *first,int *second)

{

int i;

int differ;

differ = 0;

for (i = 0; i < size; i++)

{

differ ^= arr[i];

}

differ &= -differ;

for (i = 0; i < size; i++)

{

if ((differ & arr[i]) == 0)

*first ^= arr[i];

else

*second ^= arr[i];

}

}

bitmap以及异或运算法的更多相关文章

  1. C# 异或校验算法

    C# 的异或校验算法 直接上代码 public partial class FormCRC : Form { public FormCRC() { InitializeComponent(); } p ...

  2. Java运算符 算术运算法

    运算符 算术运算法:+,-,*,/,%,++,– 复制运算符:= 关系运算符:>,<,>=,<=,==,!= instanceof 逻辑运算符:&&,||,! ...

  3. py02_04:三元运算法

    a if a > b else c     #  a>b 成立,则为真,如果a>b为假,则返回c

  4. [Java 泥水匠] Java Components 之二:算法篇之项目实践中的位运算符(有你不懂的哦)

    作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节. 交流QQ群:[编程之美 365234583] ...

  5. 不同的GCD算法

    分类: C语言程序2014-10-08 15:10 28人阅读 评论(0) 收藏 举报 gcdC语言程序位运算 早在公元前300年左右,欧几里得就在他的著作<几何原本>中给出了高效的解法- ...

  6. 记一道有意思的算法题Rotate Image(旋转图像)

    题出自https://leetcode.com/problems/rotate-image/ 内容为: You are given an n x n 2D matrix representing an ...

  7. 《OD学算法》排序

    参考 http://www.cnblogs.com/kkun/archive/2011/11/23/2260312.html http://blog.csdn.net/wuxinyicomeon/ar ...

  8. C#中常用的排序算法的时间复杂度和空间复杂度

    常用的排序算法的时间复杂度和空间复杂度   常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 ...

  9. STL函数模板(即算法)一览

    查找算法 adjacent_find:找出一个串中第一个不符合次序的地方 find,find_if:找出第一个符合条件的元素 find_first_of:在一个串中寻找第一个与另一个串中任意一个元素相 ...

随机推荐

  1. 第二次作业之——AchaoCalculator

    AchaoCalculator(阿超计算器) GIT地址 我的GitHub GIT用户名 Pastrain 学号后五位 62213 博客地址 我的博客地址 作业链接 作业内容 Part.1 配置VS中 ...

  2. 从客户端(content="xxxxx")中检测到有潜在危险的 Request.Form 值——较合理解决方案

    1,修改配置文件: <httpRuntime requestValidationMode = "2.0" /> 以上修改是必须的,因为高版本的.netframework ...

  3. 快捷定位目录 z武器

    z的源码在这里:https://github.com/rupa/z/blob/master/z.sh 1.把源码复制到你的用户目录下的z.sh文件, 2.然后用vim打开.bashrc这个目录,在最后 ...

  4. SMBus PEC

    SMBus一种I2C总线的变种 SMBus 提供了PEC方式,提高了传输的可靠性. 总线的发展都是在提高速度,提高可靠性或者提高传输效率上下功夫. PEC不具备纠错的能力,是在I2C link lay ...

  5. 2019年牛客多校第一场 H题XOR 线性基

    题目链接 传送门 题意 求\(n\)个数中子集内所有数异或为\(0\)的子集大小之和. 思路 对于子集大小我们不好维护,因此我们可以转换思路变成求每个数的贡献. 首先我们将所有数的线性基的基底\(b\ ...

  6. 关于srping的AOP事务管理问题,自定义切面是否导致事务控制失效

    applicationContext.xml: <!-- 方法调用时间记录 --> <bean id="methodExecuteTime" class=&quo ...

  7. ARTS-week3

    Algorithm 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度.不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件 ...

  8. Thinkphp下记录和统计时间(微秒)和内存使用情况

    * 记录和统计时间(微秒)和内存使用情况 * 使用方法: * <code> * G('begin'); // 记录开始标记位 * // ... 区间运行代码 * G('end'); // ...

  9. JDK1.8 java.io.Serializable接口详解

    java.io.Serializable接口是一个标志性接口,在接口内部没有定义任何属性与方法.只是用于标识此接口的实现类可以被序列化与反序列化.但是它的奥秘并非像它表现的这样简单.现在从以下几个问题 ...

  10. 学习Spring-Data-Jpa(十)---注解式方法查询之@Query、@Modifying与派生delete

    1.@Query 对于少量的查询,使用@NamedQuery在实体上声明查询是一种有效的办法,并且可以很好的工作.由于查询本身绑定到执行它们的java方法,实际上可以通过Spring-Data-Jpa ...