📌  相关文章
📜  给定集合的所有可能子集的按位或的总和

📅  最后修改于: 2021-05-25 03:25:30             🧑  作者: Mango

给定一个大小为n的数组arr [],我们需要找到所有子集的值之和。
先决条件:给定集合的子集总和
例子 :

Input :  arr[] = {1, 2, 3}
Output : 18
Total Subsets = 23 -1= 7 
1 = 1
2 = 2
3 = 3
1 | 2 = 3
1 | 3 = 3
2 | 3 = 3
1 | 2 | 3 = 3
0(empty subset)
Now SUM of all these ORs = 1 + 2 + 3 + 3 +
                            3 + 3 + 3
                          = 18

Input : arr[] = {1, 2, 3}
Output : 18
 

天真的方法是对array []元素的所有可能组合进行“或”运算,然后对所有值进行求和。这种方法的时间复杂度呈指数增长,因此对于较大的n值来说,这不会更好。
一种有效的方法是找到有关OR属性的模式。现在再次考虑二进制形式的子集,例如:

1 = 001
    2 = 010
    3 = 011
1 | 2 = 011
1 | 3 = 011
2 | 3 = 011
1|2|3 = 011

为了对数组中所有可能的元素取或,我们在这里考虑了第i位为1的所有可能子集。
现在,考虑所有结果OR的第i位,仅当子集中元素的所有第i位为0时,它才为零。
第i位为1的子集数=可能的子集总数–第i位为全0的子集。这里,总子集= 2 ^ n – 1和所有第i位为0的子集= 2 ^(所有元素的第i位为零的计数)数组的总和)– 1.现在,第i位为1的总子集OR =(2 ^ n-1)-(2 ^(第i位为零的计数)-1)。这些值为1的位贡献的总价值=总子集或第i个位为1 *(2 ^ i)。
现在,总和=(第i位为1的总子集)* 2 ^ i +(第i + 1位为i + 1的总子集)* 2 ^(i + 1)+………+(32位为1的总子集)* 2 ^ 32。

C++
// CPP code to find the OR_SUM
#include 
using namespace std;
 
#define INT_SIZE 32
 
// function to find the OR_SUM
int ORsum(int arr[], int n)
{
    // create an array of size 32
    // and store the sum of bits
    // with value 0 at every index.
    int zerocnt[INT_SIZE] = { 0 };
 
    for (int i = 0; i < INT_SIZE; i++)    
        for (int j = 0; j < n; j++)       
            if (!(arr[j] & 1 << i))
                zerocnt[i] += 1;           
     
    // for each index the OR sum contributed
    // by that bit of subset will be 2^(bit index)
    // now the OR of the bits is 0 only if
    // all the ith bit of the elements in subset
    // is 0.
    int ans = 0;
    for (int i = 0; i < INT_SIZE; i++)
    {
        ans += ((pow(2, n) - 1) -
               (pow(2, zerocnt[i]) - 1)) *
                pow(2, i);
    }
 
    return ans;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3 };
    int size = sizeof(arr) / sizeof(arr[0]);
    cout << ORsum(arr, size);
    return 0;
}


Java
// Java code to find
// the OR_SUM
import java.io.*;
 
class GFG {
     
static int INT_SIZE = 32;
 
    // function to find
    // the OR_SUM
    static int ORsum(int []arr, int n)
    {
         
        // create an array of size 32
        // and store the sum of bits
        // with value 0 at every index.
        int zerocnt[] = new int[INT_SIZE] ;
     
        for (int i = 0; i < INT_SIZE; i++)    
            for (int j = 0; j < n; j++)    
                if ((arr[j] & 1 << i) == 0)
                    zerocnt[i] += 1;        
         
        // for each index the OR
        // sum contributed by that
        // bit of subset will be
        // 2^(bit index) now the OR
        // of the bits is 0 only if
        // all the ith bit of the 
        // elements in subset is 0.
        int ans = 0;
        for (int i = 0; i < INT_SIZE; i++)
        {
            ans += ((Math.pow(2, n) - 1) -
                (Math.pow(2, zerocnt[i]) - 1)) *
                                 Math.pow(2, i);
        }
     
        return ans;
         
    }
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3 };
        int size = arr.length;
        System.out.println(ORsum(arr, size));
         
    }
}
 
// This code is contributed by Sam007


Python3
INT_SIZE = 32
 
# function to find the OR_SUM
def ORsum(arr, n):
    # create an array of size 32
    # and store the sum of bits
    # with value 0 at every index.
    zerocnt = [0 for i in range(INT_SIZE)]
 
    for i in range(INT_SIZE):   
        for j in range(n):   
            if not (arr[j] & (1 << i)):
                zerocnt[i] += 1           
     
    # for each index the OR sum contributed
    # by that bit of subset will be 2^(bit index)
    # now the OR of the bits is 0 only if
    # all the ith bit of the elements in subset
    # is 0.
    ans = 0
    for i in range(INT_SIZE):
        ans += ((2 ** n - 1) - (2 ** zerocnt[i] - 1)) * 2 ** i
 
    return ans
 
# Driver code
 
if __name__ == "__main__":
    arr= [1, 2, 3]
    size = len(arr)
    print(ORsum(arr, size))
 
# This code is contributed by vaibhav29498


C#
// C# code to find
// the OR_SUM
using System;
 
class GFG {
     
static int INT_SIZE = 32;
 
    // function to find
    // the OR_SUM
    static int ORsum(int []arr, int n)
    {
         
        // create an array of size 32
        // and store the sum of bits
        // with value 0 at every index.
        int []zerocnt = new int[INT_SIZE] ;
     
        for (int i = 0; i < INT_SIZE; i++)    
            for (int j = 0; j < n; j++)    
                if ((arr[j] & 1 << i) == 0)
                    zerocnt[i] += 1;        
         
        // for each index the OR
        // sum contributed by that
        // bit of subset will be
        // 2^(bit index) now the OR
        // of the bits is 0 only if
        // all the ith bit of the
        // elements in subset is 0.
        int ans = 0;
        for (int i = 0; i < INT_SIZE; i++)
        {
            ans += (int)(((Math.Pow(2, n) - 1) -
                 (Math.Pow(2, zerocnt[i]) - 1)) *
                                Math.Pow(2, i));
        }
     
        return ans;
         
    }
     
    // Driver Code
    public static void Main()
    {
        int []arr = {1, 2, 3};
        int size = arr.Length;
        Console.Write(ORsum(arr, size));
         
    }
}
 
// This code is contributed by nitin mittal


PHP


Javascript


输出:
18

时间复杂度: O(n)
辅助空间: O(n)