📜  查找数组中k个元素的最大异或

📅  最后修改于: 2021-04-26 09:48:41             🧑  作者: Mango

给定一个由n个整数和一个整数K组成的数组arr [] 。任务是找到给定数组的大小为K的最大xor子集。

例子:

天真的方法:遍历数组大小为K的所有子集,并在其中找到最大xor。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the maximum xor for a
// subset of size k from the given array
int Max_Xor(int arr[], int n, int k)
{
  
    // Initialize result
    int maxXor = INT_MIN;
  
    // Traverse all subsets of the array
    for (int i = 0; i < (1 << n); i++) {
  
        // __builtin_popcount() returns the number
        // of sets bits in an integer
        if (__builtin_popcount(i) == k) {
  
            // Initialize current xor as 0
            int cur_xor = 0;
            for (int j = 0; j < n; j++) {
  
                // If jth bit is set in i then include
                // jth element in the current xor
                if (i & (1 << j))
                    cur_xor = cur_xor ^ arr[j];
            }
  
            // Update maximum xor so far
            maxXor = max(maxXor, cur_xor);
        }
    }
    return maxXor;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = sizeof(arr) / sizeof(int);
    int k = 3;
  
    cout << Max_Xor(arr, n, k);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG 
{
  
// Function to return the maximum xor for a
// subset of size k from the given array
static int Max_Xor(int arr[], int n, int k)
{
  
    // Initialize result
    int maxXor = Integer.MIN_VALUE;
  
    // Traverse all subsets of the array
    for (int i = 0; i < (1 << n); i++) 
    {
  
        // __builtin_popcount() returns the number
        // of sets bits in an integer
        if (Integer.bitCount(i) == k)
        {
  
            // Initialize current xor as 0
            int cur_xor = 0;
            for (int j = 0; j < n; j++)
            {
  
                // If jth bit is set in i then include
                // jth element in the current xor
                if ((i & (1 << j)) == 0)
                    cur_xor = cur_xor ^ arr[j];
            }
  
            // Update maximum xor so far
            maxXor = Math.max(maxXor, cur_xor);
        }
    }
    return maxXor;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = arr.length;
    int k = 3;
  
    System.out.println(Max_Xor(arr, n, k));
}
}
  
// This code is contributed by PrinciRaj1992


Python3
# Python implementation of the approach
  
MAX = 10000
MAX_ELEMENT = 50
  
dp =[[[-1 for i in range(MAX)] 
    for j in range(MAX_ELEMENT)] 
    for k in range(MAX_ELEMENT)]
  
# Function to return the maximum xor for a
# subset of size j from the given array
def Max_Xor(arr, i, j, mask, n):
    if (i >= n):
          
        # If the subset is complete then return
        # the xor value of the selected elements
        if (j == 0):
            return mask
        else:
            return 0
      
    # Return if already calculated for some
    # mask and j at the i'th index
    if (dp[i][j][mask] != -1):
        return dp[i][j][mask]
      
    # Initialize answer to 0
    ans = 0
      
    # If we can still include elements in our subset
    # include the i'th element
    if (j > 0):
        ans = Max_Xor(arr, i + 1, j - 1, mask ^ arr[i], n)
          
    # Exclude the i'th element
    # ans store the max of both operations
    ans = max(ans, Max_Xor(arr, i + 1, j, mask, n))
    dp[i][j][mask] = ans
    return ans
  
# Driver code
arr = [2, 5, 4, 1, 3, 7, 6, 8]
n = len(arr)
k = 3
  
print(Max_Xor(arr, 0, k, 0, n))
  
# This code is contributed by shubhamsingh10


C#
// C# implementation of the approach
using System;
      
class GFG 
{
  
// Function to return the maximum xor for a
// subset of size k from the given array
static int Max_Xor(int []arr, int n, int k)
{
  
    // Initialize result
    int maxXor = int.MinValue;
  
    // Traverse all subsets of the array
    for (int i = 0; i < (1 << n); i++) 
    {
  
        // __builtin_popcount() returns the number
        // of sets bits in an integer
        if (bitCount(i) == k)
        {
  
            // Initialize current xor as 0
            int cur_xor = 0;
            for (int j = 0; j < n; j++)
            {
  
                // If jth bit is set in i then include
                // jth element in the current xor
                if ((i & (1 << j)) == 0)
                    cur_xor = cur_xor ^ arr[j];
            }
  
            // Update maximum xor so far
            maxXor = Math.Max(maxXor, cur_xor);
        }
    }
    return maxXor;
}
  
static int bitCount(long x)
{
    int setBits = 0;
    while (x != 0)
    {
        x = x & (x - 1);
        setBits++;
    }
    return setBits;
} 
  
// Driver code
public static void Main(String[] args)
{
    int []arr = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = arr.Length;
    int k = 3;
  
    Console.WriteLine(Max_Xor(arr, n, k));
}
}
  
// This code is contributed by Princi Singh


C++
// C++ implementation of the approach
#include 
using namespace std;
  
#define MAX 10000
#define MAX_ELEMENT 50
  
int dp[MAX_ELEMENT][MAX_ELEMENT][MAX];
  
// Function to return the maximum xor for a
// subset of size j from the given array
int Max_Xor(int arr[], int i, int j, int mask, int n)
{
    if (i >= n) {
  
        // If the subset is complete then return
        // the xor value of the selected elements
        if (j == 0)
            return mask;
        else
            return 0;
    }
  
    // Return if already calculated for some
    // mask and j at the i'th index
    if (dp[i][j][mask] != -1)
        return dp[i][j][mask];
  
    // Initialize answer to 0
    int ans = 0;
  
    // If we can still include elements in our subset
    // include the i'th element
    if (j > 0)
        ans = Max_Xor(arr, i + 1, j - 1, mask ^ arr[i], n);
  
    // Exclude the i'th element
    // ans store the max of both operations
    ans = max(ans, Max_Xor(arr, i + 1, j, mask, n));
  
    return dp[i][j][mask] = ans;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = sizeof(arr) / sizeof(int);
    int k = 3;
  
    memset(dp, -1, sizeof(dp));
  
    cout << Max_Xor(arr, 0, k, 0, n);
  
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
  
class GFG
{
static int MAX = 10000;
static int MAX_ELEMENT = 50;
  
static int [][][] dp = new int[MAX_ELEMENT][MAX_ELEMENT][MAX];
  
// Function to return the maximum xor for a
// subset of size j from the given array
static int Max_Xor(int arr[], int i, 
                   int j, int mask, int n)
{
    if (i >= n) 
    {
  
        // If the subset is complete then return
        // the xor value of the selected elements
        if (j == 0)
            return mask;
        else
            return 0;
    }
  
    // Return if already calculated for some
    // mask and j at the i'th index
    if (dp[i][j][mask] != -1)
        return dp[i][j][mask];
  
    // Initialize answer to 0
    int ans = 0;
  
    // If we can still include elements in our subset
    // include the i'th element
    if (j > 0)
        ans = Max_Xor(arr, i + 1, j - 1, 
                      mask ^ arr[i], n);
  
    // Exclude the i'th element
    // ans store the max of both operations
    ans = Math.max(ans, Max_Xor(arr, i + 1, j, 
                                mask, n));
  
    return dp[i][j][mask] = ans;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = arr.length;
    int k = 3;
  
    for(int i = 0; i < MAX_ELEMENT; i++)
    {
        for(int j = 0; j < MAX_ELEMENT; j++)
        {
            for(int l = 0; l < MAX; l++)
            dp[i][j][l] = -1;
        }
    }
  
    System.out.println(Max_Xor(arr, 0, k, 0, n));
}
}
  
// This code is contributed by Princi Singh


Python3
# Python implementation of the approach
  
MAX = 10000
MAX_ELEMENT = 50
  
dp =[[[-1 for i in range(MAX)] for j in range(MAX_ELEMENT)] for k in range(MAX_ELEMENT)]
  
# Function to return the maximum xor for a
# subset of size j from the given array
def Max_Xor(arr, i, j, mask, n):
    if (i >= n):
          
        # If the subset is complete then return
        # the xor value of the selected elements
        if (j == 0):
            return mask
        else:
            return 0
      
    # Return if already calculated for some
    # mask and j at the i'th index
    if (dp[i][j][mask] != -1):
        return dp[i][j][mask]
      
    # Initialize answer to 0
    ans = 0
      
    # If we can still include elements in our subset
    # include the i'th element
    if (j > 0):
        ans = Max_Xor(arr, i + 1, j - 1, mask ^ arr[i], n)
          
    # Exclude the i'th element
    # ans store the max of both operations
    ans = max(ans, Max_Xor(arr, i + 1, j, mask, n))
    dp[i][j][mask] = ans
    return ans
  
  
# Driver code
  
arr = [2, 5, 4, 1, 3, 7, 6, 8]
n = len(arr)
k = 3
  
print(Max_Xor(arr, 0, k, 0, n))
  
# This code is contributed by shubhamsingh10


输出:
15

高效的方法:可以使用动态编程解决问题。创建一个dp表dp [i] [j] [mask] ,该表存储第i索引(有或没有包含)时可能的最大xor, j表示我们可以在K个元素的子集中包含的剩余元素数。掩码是所有选择的元素的异或,直到第i索引为止。
注意:由于dp阵列需要空间,因此该方法仅适用于较小的阵列。

下面是上述方法的实现:

C++

// C++ implementation of the approach
#include 
using namespace std;
  
#define MAX 10000
#define MAX_ELEMENT 50
  
int dp[MAX_ELEMENT][MAX_ELEMENT][MAX];
  
// Function to return the maximum xor for a
// subset of size j from the given array
int Max_Xor(int arr[], int i, int j, int mask, int n)
{
    if (i >= n) {
  
        // If the subset is complete then return
        // the xor value of the selected elements
        if (j == 0)
            return mask;
        else
            return 0;
    }
  
    // Return if already calculated for some
    // mask and j at the i'th index
    if (dp[i][j][mask] != -1)
        return dp[i][j][mask];
  
    // Initialize answer to 0
    int ans = 0;
  
    // If we can still include elements in our subset
    // include the i'th element
    if (j > 0)
        ans = Max_Xor(arr, i + 1, j - 1, mask ^ arr[i], n);
  
    // Exclude the i'th element
    // ans store the max of both operations
    ans = max(ans, Max_Xor(arr, i + 1, j, mask, n));
  
    return dp[i][j][mask] = ans;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = sizeof(arr) / sizeof(int);
    int k = 3;
  
    memset(dp, -1, sizeof(dp));
  
    cout << Max_Xor(arr, 0, k, 0, n);
  
    return 0;
}

Java

// Java implementation of the approach
import java.util.*;
  
class GFG
{
static int MAX = 10000;
static int MAX_ELEMENT = 50;
  
static int [][][] dp = new int[MAX_ELEMENT][MAX_ELEMENT][MAX];
  
// Function to return the maximum xor for a
// subset of size j from the given array
static int Max_Xor(int arr[], int i, 
                   int j, int mask, int n)
{
    if (i >= n) 
    {
  
        // If the subset is complete then return
        // the xor value of the selected elements
        if (j == 0)
            return mask;
        else
            return 0;
    }
  
    // Return if already calculated for some
    // mask and j at the i'th index
    if (dp[i][j][mask] != -1)
        return dp[i][j][mask];
  
    // Initialize answer to 0
    int ans = 0;
  
    // If we can still include elements in our subset
    // include the i'th element
    if (j > 0)
        ans = Max_Xor(arr, i + 1, j - 1, 
                      mask ^ arr[i], n);
  
    // Exclude the i'th element
    // ans store the max of both operations
    ans = Math.max(ans, Max_Xor(arr, i + 1, j, 
                                mask, n));
  
    return dp[i][j][mask] = ans;
}
  
// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 5, 4, 1, 3, 7, 6, 8 };
    int n = arr.length;
    int k = 3;
  
    for(int i = 0; i < MAX_ELEMENT; i++)
    {
        for(int j = 0; j < MAX_ELEMENT; j++)
        {
            for(int l = 0; l < MAX; l++)
            dp[i][j][l] = -1;
        }
    }
  
    System.out.println(Max_Xor(arr, 0, k, 0, n));
}
}
  
// This code is contributed by Princi Singh

Python3

# Python implementation of the approach
  
MAX = 10000
MAX_ELEMENT = 50
  
dp =[[[-1 for i in range(MAX)] for j in range(MAX_ELEMENT)] for k in range(MAX_ELEMENT)]
  
# Function to return the maximum xor for a
# subset of size j from the given array
def Max_Xor(arr, i, j, mask, n):
    if (i >= n):
          
        # If the subset is complete then return
        # the xor value of the selected elements
        if (j == 0):
            return mask
        else:
            return 0
      
    # Return if already calculated for some
    # mask and j at the i'th index
    if (dp[i][j][mask] != -1):
        return dp[i][j][mask]
      
    # Initialize answer to 0
    ans = 0
      
    # If we can still include elements in our subset
    # include the i'th element
    if (j > 0):
        ans = Max_Xor(arr, i + 1, j - 1, mask ^ arr[i], n)
          
    # Exclude the i'th element
    # ans store the max of both operations
    ans = max(ans, Max_Xor(arr, i + 1, j, mask, n))
    dp[i][j][mask] = ans
    return ans
  
  
# Driver code
  
arr = [2, 5, 4, 1, 3, 7, 6, 8]
n = len(arr)
k = 3
  
print(Max_Xor(arr, 0, k, 0, n))
  
# This code is contributed by shubhamsingh10
输出:
15