如何准备:

Bit manipulation can be a scary thing to many candidates, but it doesn’t need to be! If you’re shaky on bit manipulation, we recommend doing a couple of arithmetic-like problems to boost your skills Compute the following by hand: 1010 - 0001 1010
+ 0110 1100^1010 1010 << 1 1001^1001 1001 & 1100 1010 >> 1 0xFF - 1 0xAB + 0x11 If you’re still uncomfortable, examine very carefully what happens when you do subtraction, addition, etc in base 10 Can you repeat that work in base 2?

很多应聘者都很害怕“位操作”的题目,害怕确实是没有必要的。如果真的在位操作方面不太擅长的话,建议你还是通过在一些练习好好准备。笔算下面的题目:


如果这些题目做的时候还有困惑的话,那就把我们平时做10进制加减的规则联系到2进制上。

NOTE: The Windows Calculator knows how to do lots of operations in binary, including ADD, SUBTRACT, AND and OR. Go to View Programmer to get into binary mode while you practice.

注意:windows自带的计算器能完成很多2进制下的计算,加减法,求与求门等。点击计算机的“查看” -> “科学型”,再按F7就能进入二进制模式计算了。

Things to Watch Out For:

注意事项:

» It’s really easy to make mistakes on these problems, so be careful! When you’re writing code, stop and think about what you’re writing every couple of lines - or, better yet, test your code mid-way through! When you’re done, check through your
entire code » If you’re bit shifting, what happens when the digits get shifted off the end? Make sure to think about this case to ensure that you’re handling it correctly And (&): 0 & 0 = 0 1 & 0 = 0 0 & 1 = 0 1 & 1 = 1 Or (|): 0 | 0 = 0 1 | 0 = 1 0 | 1 =
1 1 | 1 = 1 Xor (^): 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0

*在写代码的时候涉及到位操作一定要小心。边写的时候就要边想下,最好还能测试下。最后全部写完以后再测试一次。

*在做移位操作的时候,特别注意移位超过边界的时候如何处理。一定要想清楚然后。

Left Shift:

左位移:

x << y means x shifted y bits to the left If you start shifting and you run out of space, the bits just “drop off” For example: 00011001 << 2 = 01100100 00011001 << 4 = 10010000

x< < 表示将x向左位移y位。移动时超出的部分直接丢弃。

Right Shift:

右位移:

x >> y means x shifted y bits to the right If you start shifting and you run out of space, the bits just “drop off” the end Example: 00011001 >> 2 = 00000110 00011001 >> 4 = 00000001

x>>y 表示将x向右位移y位。移动时超出的部分直接丢弃。

5 1 You are given two 32-bit numbers, N and M, and two bit positions, i and j Write a method to set all bits between i and j in N equal to M (e g , M becomes a substring of N located at i and starting at j) EXAMPLE: Input: N = 10000000000, M = 10101,
i = 2, j = 6 Output: N = 10001010100

5.1 给你两个32位整数N,M,还有表示位置的i和j。实现方法使得N的i至j位等于M。例如:输入  N = 10000000000, M = 10101, i = 2, j = 6 输出 N = 10001010100
5.1解答:

解法很简单,首先将N的i到j位清零,然后再将M左移i位,最后将两数做或。

5 2 Given a (decimal - e g 3 72) number that is passed in as a string, print the binary rep- resentation If the number can not be represented accurately in binary, print “ERROR”

5.2 以字符串形式传入一个十进制数(例如3.72),输出它的二进制表示形式。如果不能准确表示则输出"ERROR"

5.2解答:首先我们思考一下小数是如何用二进制表示的。以n = 0.101 = 1 * (1/2^1) + 0 * (1/2^2) + 1 * (1/2^3)为例。

打印输出整数部分是非常简单和直接的。小数部分我则采用将n*2,取整数部分,这就相当于“移位”的思想。


如果r>1,那么说明小数点后第一位为1。一直这样做,我们就能得到小数的二进制表示方法。

(译者注:本题作者理解为若32位小数仍无法表示则认为该数无法用二进制准确表示。更为准确的是判断标准为:在转换的任意阶段,若小数部分的最后一个数字非5,在该数无法被二进制数准确表示。)

5 3 Given an integer, print the next smallest and next largest number that have the same number of 1 bits in their binary representation

5.3 给定一个整数,输出与这整数在二进制表示下有相同个数“1",大于n的最小值和小于n的最大值。
5.3解答:

暴力算法:

最简单的方法就是从n向上/向下例举,判断是否有对应个数的”1“。但是这样的方法一点技术含量也没有。

根据数字性质:

首先观察

* 若降一个”1“变为”0“,再另一个”0“必须变为1;

* 若将第i位的0变为了1,第j为的1变为了0,那么数字大小的变化为2^i - 2^j;

* 若要变大数字必须让i大于j。

求大于n的最小值:

* 将n转化为二进制,从右往左依次遍历各位,在经过1后,遇到的第一个0,将其置1。这样就是个数字增大了2^i。例:xxxxx011100 变成 xxxxx111100

* 将i位右边的1置0,这样数字总的变化2^i-2^(i-1)。例:xxxxx111100 变成 xxxxx101100

* 为了让大于n的最小值,将i-1之后的1都移到最右端。

求小于n的最大值,方法类似:

* 将n转化为二进制,从右往左一次遍历各位,在经过0后遇到的第一个。例如xxxxx100011 变为 xxxxx000011

* 将i位右边的0置为1。例如xxxxx000011 变为 xxxxx010011。

* 为求最大值,将i-1位后的1尽量往左移到。

有了算法,开始着手写代码的时候记得将一些常用的方法放到一个公共的类中,写出整洁的代码。

5 4 Explain what the following code does: ((n & (n-1)) == 0)

5.4 解释下面表达式的含义 ((n & (n-1)) == 0)
5.4解答

我们来反向思考这个问题。

A&B=0是什么意思呢?它表示A和B两个数的二进制数每一位都不相同。那么n & (n-1)=0,说明n和n-1也没有相同的位。

那n-1又表示什么意义呢?从下面的例子你能看发现什么呢?


当你做减法的时候,主要看最低位,如果最低位为1,那么最低位直接变0;如果最低位为零,那么向高位借1,再减。从低位开始向高位将0变为1,直到借位的那一位。那么n和n-1的关系将会如下例所示:


如果n&(n-1)为0的话,说明例子中的abcde均为0,也就是说n中只有一位为1。也就是说n为2的整数次幂。

5 5 Write a function to determine the number of bits required to convert integer A to integer B Input: 31, 14 Output: 2

5.5 实现函数计算将整数从A变成B需要变动几位。例如 输入:31,14 输出 2
5.5解答:

本题的解题关键在于发现A和B之间有多少位是不同的。那如何判断A和B那些位不同呢?对XOR!

将获得A和B不同的部分,统计出有多少个1就能判断需要变动几位了。

5 6 Write a program to swap odd and even bits in an integer with as few instructions as possible (e g , bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped, etc)

5.6 实现方法将一个整数中的偶数位和奇数位交换。(例如:将0位和1位交换,2位和3位交换)
5.6解答:

用10101010(0xAA)这样的掩码提取出偶数位的信息,类似的用0x55提取奇数位的信息。然后错位求或即可。

5 7 An array A[1 n] contains all the integers from 0 to n except for one number which is missing In this problem, we cannot access an entire integer in A with a single operation The elements of A are represented in binary, and the only operation
we can use to access them is “fetch the jth bit of A[i]”, which takes constant time Write code to find the missing integer Can you do it in O(n) time?

5.7 一个数组A[1,n]能容纳n个数字,现将0到n这n+1个数字,随机的放入到数组中。最后会有一个数字没有进入数组。现在让你找出这个数字。但是有如下的限制,不能直接访问数组的整个元素,只能访问“A[i]的第j位”。写出代码找出该元素。能否将时间复杂度控制在O(n)。
5.7解答:

(译者注:作者这里假设n为奇数。)

首先我们将0到n的所有数字的二进制表达列出来。那么我们可以发现最低位的,大概是这样的情况:count(0)>=count(1)。

如果我们从中移除了一个数字,会怎么样呢?


如果移除的数最低位为0,那么count(1)>=count(0);如果移除的是1,那么count(0)>count(1)。如果n次访问每个数的最低位,那么用以上的准则我们就能判断出没有进入数组的那个数字的最后一位是什么。如果最低位是0的话,那就可以排除最低位为1的元素;如最低位为1,那就可以排除末尾为0的。

那下一步怎么办呢?看次低位的情况?那么我以n=5,未入数组的数字为3。经过上一轮的排除后,剩下的数字如图所示:


那么现在次低位的情况为0 0 1 0 1 0 ,根据之前的逻辑我们知道,次低位应该是1。那么我们继续排除。只保留末尾为11的元素。剩下的就是:


再继续看倒数第三位。同样方法知道第三位应该是0。那么我们确定出了丢失的元素。

根据以上的方法,确定实现代码如下:


那算法的时间复杂是多少呢?第一次扫描了N次的最低位,第二次为N/2......以此类推,根据下式子:


所以我的算法的复杂度为O(n)。

【IT笔试面试题整理】位操作的更多相关文章

  1. Java笔试面试题整理第八波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51388516 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  2. Java笔试面试题整理第六波(修正版)

    转载至:http://blog.csdn.net/shakespeare001/article/details/51330745 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  3. Java笔试面试题整理第五波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51321498 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  4. Java笔试面试题整理第四波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51274685 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  5. Java笔试面试题整理第三波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51247785 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  6. Java笔试面试题整理第二波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51200163 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  7. Java笔试面试题整理第一波

    转载至:http://blog.csdn.net/shakespeare001/article/details/51151650 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...

  8. C++笔试面试题整理

    朋友给出的一些常见的C++面试题,特整理如下,后期遇到新的再更新. 面试题 列举并解释C++中的四种运算符转化,说明它们的不同点: static_cast: 在功能上基本上与C风格的类型转换一样强大, ...

  9. 【IT笔试面试题整理】给定一个数组a[N]构造数组b [N]

    [来源]:腾讯2013实习生笔试   给定一个数组a[N],我们希望构造数组b [N],其中b[j]=a[0]*a[1]-a[N-1] / a[j])空间复杂度和O(n)的时间复杂度:除遍历计数器与a ...

随机推荐

  1. 当Windows Phone遇到Windows 8

    三年前,Windows Phone系统的发布表示了微软夺回移动市场的决心.一年前,Windows 8的发布,昭示着Windows Phone系统取得的成功——扁平化图标风格.动态磁贴.SkyDrive ...

  2. hive-内部表和外部表 对比

    建表时,需要考虑究竟建内部表还是外部表,内部表和外部表都有哪些不同? 内部表: 1. 数据存储位置:数据最终会被移动到 hive.metastore.warehouse.dir指定的路径下,以表名创建 ...

  3. Git和SourceTree配合使用

    Git介绍 git是当今最强大的本地的分布式代码版本管理工具. git的核心概念与操作:开发环境,本地仓库,远程仓库.他们的关系如下图: 与CVS及SVN的比较: CVS及SVN都是集中式的版本控制系 ...

  4. 用JavaScript写的动态表格

    实现的功能有Table表格添加,删除.输入,删除的全选,单行删除. HTML代码部分 <body> <form> <table border="1" ...

  5. JVM中的新生代、老年代和永生代

    1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

  6. [leetcode 50]remove element

    1 题目 Given an array and a value, remove all instances of that value in place and return the new leng ...

  7. Win7的“以管理员身份运行”

    如果HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA被设置为0,则"以管理员身份运行" ...

  8. 获取用户真实ip

    public static string GetRealIP() { string result = System.Web.HttpContext.Current.Request.Headers[&q ...

  9. [Element-UI] 使用Element-UI的DateTimePicker组件报错:Cannot read property 'getHours' of undefined

    使用Element-UI组件的DateTimePicker,如下: <template> <div class="block"> <span clas ...

  10. haproxy监测页面参数简释

    Queue Cur: current queued requests //当前的队列请求数量Max:max queued requests     //最大的队列请求数量Limit:         ...