Java中的不匹配位数
在本教程中,我们将讨论Java中不匹配位数的问题。在这个问题中,我们得到了两个数字(f1和f2)。我们的任务是,当我们比较两个数字的二进制表示时,找出不匹配的位数。假设每个数字都适合在8位上。
例1 :
输入
int f1 = 9
int f2 = 15
输出
不匹配的比特总数为2。
解释 。
数字9的8位二进制表示是00001001,数字15的8位二进制表示是00001111。如果我们从左到右比较这两个二进制表示法,我们发现前五位是匹配的。第六位和第七位不匹配,因为数字9的位数都是0,数字15的位数都是1。因此,有两个位不匹配。因此,输出为2。
例 2 :
输入
int f1 = 32
int f2 = 31
输出
错位的总数是6。
解释 。
数字32的8位二进制表示是00100000,数字31的8位二进制表示是00011111。如果我们从左到右比较这两个二进制表示法,我们发现前两个比特是匹配的。在这之后,直到第八位都有不匹配。第三位对数字32来说是1,对数字31来说是0,其余的其他位,数字32的值是0,数字31的值是1。因此,有6位不匹配。因此,输出为6。
例3 :
输入
int f1 = 40
int f2 = 40
输出
不匹配的比特总数为0。
解释 。
由于两个数字都是一样的,它们的二进制表示也是一样的。因此,不匹配的位数为零。因此,输出为0。
简单的方法
简单的方法是首先将两个数字(f1和f2)转换成它们的二进制表示。然后将它们的二进制表示存入数组列表(一个用于f1的二进制表示,另一个用于f2的二进制表示)。之后,使用一个循环,我们可以比较这些位并找出答案。观察下面的程序。
文件名:MismatchingBits.java
输出 。
复杂度分析: 程序中使用了四个while循环和一个for循环。在所有这五个循环中,两个while循环和一个for循环只会运行一个恒定的时间。最后两个while循环和for循环在最坏的情况下需要O(8)时间,这是一个常数。所以,程序的总体时间复杂度取决于前两个while循环。第一个while-loop需要O(dig1)时间,第二个循环需要O(dig2)时间。因此,程序的总体时间复杂度是O(dig1 + dig2),其中dig1是数字f1中存在的数字总数,dig2是数字f2中存在的数字总数。该程序的空间复杂度需要O(8)次,这是一个常数。
我们可以避免使用数组列表来存储给定数字的比特。下面的程序显示了这一点。
文件名: MisMatchBits1.java
输出 。
复杂性分析: 该程序只使用了一个循环,只运行了O(8)次,这是不变的。此外,该程序没有使用任何额外的空间。因此,该程序的时间和空间复杂度都是O(1)。
使用XOR运算符
另一种找到不匹配位数的方法是使用位向XOR。每当我们在两个数字上应用逐位XOR时,我们会得到一个数字,其被设置的那些位在这两个数字中不匹配。现在,计算一下XOR值中被设置的位数。这个计算值就是我们的答案。让我们举个例子来理解这个问题。
我们取两个数字,10和2。现在,10 ^ 2 = 8。这是因为1010 ^ 0010 = 1000(值是8)。我们看到第一位(从右到左开始)被设置为1,因为数字10的第一位是1,数字2是0(不匹配)。其余的位都与两个数字相匹配。因此,在XOR值中其余的位是0。
在XOR值中,我们看到只有一个位被设置。因此,数字10和2的不匹配位数是1。 观察以下程序。
文件名:MismatchingBits2.java
输出 。
复杂度分析: 该程序的时间以及空间复杂度是常数,即O(1)。
注意:我们在本教程中讨论了三个程序,渐进地看,所有程序的时间复杂性都是一样的。然而,在所有这三个程序中,第三个程序的复杂性是最好的。这是因为第三个程序中使用的while-loop只运行O( setBits ) 次,其中 setBits 是两个给定数字的XOR值中的set位数。通常情况下,在一个XOR值中,设置位的数量是相当少的。因此,在大多数情况下,第三个程序的while-loop的运行次数甚至少于O(8)次。