📜  从给定的数组中找到所有无序对的 XNOR 和

📅  最后修改于: 2022-05-13 01:56:06.664000             🧑  作者: Mango

从给定的数组中找到所有无序对的 XNOR 和

给定一个大小为N的数组arr[] ,任务是从给定数组中找到所有可能的无序对的所有 XNOR 值的总和。

例子:

方法:在 XNOR 操作之后设置位的唯一可能情况是两个必须相同。请按照以下步骤解决问题:

  • 维护一个大小为 30 的位数组。左起第 0位表示2^29包含在二进制表示中,从左起第 29位表示2^0包含在二进制表示中。
  • 对于每个元素,如果设置了第 i 个位,则增加位数的第 i 个位置。
  • 遇到包含“1”MSB后,计算“0”和“1”位。
  • 在遇到“1”位之前,所有“0”位都将被浪费。分开存放。
  • 最后,假设第 i 个位置有y 个个数。因此,对于具有(1, 1)位组合的第 i 位,有y*(y-1)/2对,结果1XNOR 。另外,假设直到相同的位置有x 个零。因此,对于具有(0, 0)位组合的第 i 位,有y*(y-1)/2对,结果1XNOR
  • 现在对于前导零的情况,将浪费的位数乘以0 的位数。对每个位位置执行此操作并计算答案。

为了更好地理解,请考虑数组 {35, 42, 27, 69} 这是数组的所有四个元素的二进制表示。

数组元素的二进制表示。

  • 带箭头的单点是该元素的第一位,即 1。因此,它是该元素的最高有效位。同样,所有其他元素的MSB绿色
  • 出现在 MSB 之前的零是浪费的位并以红色着色。这些二进制数组的大小各为 30。
  • 在 bits 数组的前 23位置中,浪费位数为 4,1数量为零0 的数量为零,如图所示。
  • 在第 24 个位置,浪费的位3 ,当在元素 69 的第 24 个元素处遇到 MSB 时, 1 的数量将为1
  • 现在在这些位中的每一个中,对于任何一对位中的 XNOR 值都为1 ,要么两者都应该是1 ,要么应该是0
  • 对于两者都应该是 1 ,它有N[i]*(N[i]-1)/2对,其中N[i]是所有元素中第 i 个位置的 1 的数量。
  • 同样,对于两者都应该是 0 ,它有M[i]*(M[i]-1)/2对,其中M[i]是所有元素中第 i 个位置的 0 的数量。因为所需的答案是所有可能性的总和。因此,对于第 i位,为所有可能的对添加2^(30-i-1)
  • 如果两者都应为 0,则还要考虑在任何元素在浪费位的相同位置具有 0(非浪费)时发生的浪费位。让浪费的位为W[i]
  • 所以总和 = (N[i]*(N[i]-1)/2)*(2^(30-i-1) + (M[i]*(M[i]-1)/2) *(2^(30-i-1) + (W[i]*M[i]*(2^(30-i-1)))其中 0<= i <=30。
  • 所以,对于上面的例子,直到第 23 位,一切都是 0。从第 24 位开始在这里列出。
  • 总计 = ((1*0)/2)*(2^6) + ((0*(-1))/2)*(2^6) + 3*0*(2^6) + ((2 *1)/2)*(2^5) + ((1*0)/2)*(2^5) + 1*1*(2^5) + ((1*0)/2)*( 2^4) + ((3*2)/2)*(2^4) + 0*3*(2^4) + ((2*1)/2)*(2^3) + ((2 *1)/2)*(2^3) + 0*2*(2^3) + ((1*0)/2)*(2^2) + ((3*2)/2)*( 2^2) + 0*3*(2^2) + ((3*2)/2)*(2^1) + ((1*0)/2)*(2^1) + 0*1 *(2^1) + ((3*2)/2)*(2^0) + ((1*0)/2)*(2^0) + 0*1*(2^0)
  • 总计 = 0 + 0 + 0 + 32 + 0 + 32 + 0 + 48 + 0 + 8 + 8 + 0 + 0 + 12 + 0 + 6 + 0 + 0 + 3 + 0 + 0
  • 因此,总和 = 149

下面是上述方法的实现。

Python3
# Python program for the above approach
 
# Function to find the required sum
 
 
def findSum(n, r):
 
    # Store the result
    result = 0
 
    # bits[i][0] and bits[i][1] has
    # count of all 1's and 0's in the
    # ith bit of all elements respectively
    # bits[i][2] has count of wasted zeroes
    # of ith bit for all elements
    bits = [[0, 0, 0] for i in range(30)]
 
    # Iterating through all elements
    for i in r:
 
        # Converting element to binary
        binary = bin(i)[2:]
 
        # zfill adds zeros to the front
        binary = binary.zfill(30)
 
        # Flag variable set to 1 after
        # first occurence of 1 (MSB)
        flag = 0
 
        # Iterating through all the bits
        for j in range(30):
            # If msb not found
            if(flag == 0):
 
                # Msb found
                if(binary[j] == '1'):
 
                    # Set flag to 1
                    flag = 1
 
                    # Incrementing number
                    # of 1's in jth bit
                    bits[j][0] += 1
 
                # If msb not found yet
                else:
                    # Incrementing number of
                    # wasted zeroes before msb
                    bits[j][2] += 1
 
                # Continue till msb is encountered
                continue
 
            # Incrementing number
            # of 1's in jth bit
            if(binary[j] == '1'):
                bits[j][0] += 1
 
            # Incrementing number
            # of 0's in jth bit
            else:
                bits[j][1] += 1
 
    # Iterating through all bits
    for i in range(30):
 
        # Total number of 1's in
        # ith bit of all elements
        y = bits[i][0]
 
        # Total number of 0's in
        # ith bit of all elements
        x = bits[i][1]
 
        # Total number of wasted 0's
        # before msb of ith bit of all elements
        msboff = bits[i][2]
 
        # y*(y-1)/2 pairs for ith bit has (1, 1)
        # bit combo which gives result 1 in XNOR
        onePairs = (y*(y-1))//2
 
        # Adding value of ith
        # bit number of (1, 1) pairs
        # times to result
        # (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.
        result += onePairs * pow(2, 30-i-1)
 
        # x*(x-1)/2 pairs for ith bit has (0, 0)
        # bit combo which gives result 1 in XNOR
        zeroPairs = ((x*(x-1))//2)
 
        # Adding value of ith bit
        # number of (0, 0) pairs
        # times to result
        # (2^(30-i-1) => 2 ^ 29, 2 ^ 28 etc.)
        result += zeroPairs * pow(2, 30-i-1)
 
        # Same for leading zeroes
        result += (msboff * x)*pow(2, 30-i-1)
 
    return result
 
 
# Driver code
if __name__ == '__main__':
    n = 5
    r = [2, 2, 2, 1, 1]
    print(findSum(n, r))


Javascript


输出
10

时间复杂度:O(30*N)
辅助空间: O(1)