C++で2つの配列の各要素同士の最大XORを求める方法
この記事では、n個の要素を持つ2つの配列AとBが与えられたとき、配列Aの各要素について配列Bのどの要素と組み合わせればXORが最大になるかを求めるプログラムをC++で作成します。
つまり、配列Aの各要素ごとに、配列Bの中からXOR値が最も大きくなる相手を選び出すのが課題です。
問題の例
具体例を使って問題を理解しましょう。
入力:
array A = {3, 6, 11, 9}
array B = {8, 2, 4, 1}
出力:
11 14 15 13
説明:
配列Aの各要素と配列Bのすべての要素とのXORの組み合わせを計算し、それぞれの最大値を選択します。
3 XOR 8 = 11 3 XOR 2 = 1 3 XOR 4 = 7 3 XOR 1 = 2 → 最大値:11 6 XOR 8 = 14 6 XOR 2 = 4 6 XOR 4 = 2 6 XOR 1 = 1 → 最大値:14 11 XOR 8 = 3 11 XOR 2 = 9 11 XOR 4 = 15 11 XOR 1 = 10 → 最大値:15 9 XOR 8 = 1 9 XOR 2 = 11 9 XOR 4 = 13 9 XOR 1 = 8 → 最大値:13
解き方のアプローチ
1. 単純な解法(計算量 O(n²))
最もシンプルな方法は、上記の例のようにすべての組み合わせを総当たりで計算し、最大のXORを出力することです。しかし、この方法は二重ループに依存するため、計算量がO(n²)となり、データ数が多い場合には非効率になります。
2. トライ(Trie)を使った効率的な解法
そこで、トライ(Trie)データ構造を活用したより効率的な解法を紹介します。トライに配列Bの全要素を2進数のビット列として格納し、配列Aの各要素との照合を行うことで最大XORを求めます。
具体的には、配列Aの各要素について最上位ビット(MSB)から順に確認し、XORの結果が1になるように「現在のビットの反対」の分岐を選択しながら辿っていきます。これを下位のビットまで繰り返すことで、各要素に対する最大XORの相手を効率よく見つけることができます。この手法により、計算量を要素数×ビット長(約32回の比較)程度まで抑えられます。
C++での実装例
以下は、配列Aの各要素と配列Bとの間で可能な最大XORを求めるプログラムです。
#include<iostream>
using namespace std;
struct trie{
int value;
trie *child[2];
};
trie * get(){
trie * root = new trie;
root -> value = 0;
root -> child[0] = NULL;
root -> child[1] = NULL;
return root;
}
void insert(trie * root, int key){
trie * temp = root;
for (int i = 31; i >= 0; i--){
bool current_bit = key & (1 << i);
if (temp -> child[current_bit] == NULL)
temp -> child[current_bit] = get();
temp = temp -> child[current_bit];
}
temp -> value = key;
}
int findMaxXor(trie * root, int element){
trie * temp = root;
for (int i = 31; i >= 0; i--){
bool bits = ( element & ( 1 << i) );
if (temp -> child[1 - bits] != NULL)
temp = temp -> child[1 - bits];
else
temp = temp -> child[bits];
}
return (element ^ temp -> value);
}
int main(){
int A[] = {3, 11, 6, 9};
int B[] = {8, 2, 4, 1};
int N = sizeof(A)/sizeof(A[0]);
trie * root = get();
for (int i = 0; i < N; i++)
insert(root, B[i]);
cout<<"The maximum possible XOR of every possible element in array A with Array B is\n";
for (int i = 0; i < N; i++)
cout <<findMaxXor(root, A[i])<<"\t";
return 0;
}
出力結果
The maximum possible XOR of every possible element in array A with Array B is 11 15 14 13
-
C++で絶対差の合計が最小となる配列要素を求める方法
このプログラムは、重複しない要素からなる配列が与えられたときに、各要素の絶対差の合計が最小となる値を求めるものです。この概念をより深く理解するために、まず必要な基礎知識をおさらいしましょう。配列(Array)とは、同じデータ型の要素を格納するためのコンテナです。配列の長さは事前に定義しておく必要があります。絶対差(Absolute Difference)とは、2つの数値の差の絶対値のことです。つまり、差は常に正の値となり、負の値は正の値に変換されます。各要素について最小絶対差を求め、その合計を計算します。最小絶対差の公式は次のとおりです。Minimum Absolute Difference
-
Pythonで配列の要素から最大XORを求めるプログラムの作成方法
非負の整数だけを含む配列 nums と、複数のクエリをまとめた配列 queries が与えられるとします。queries[i] はペア (xi, mi) を表しています。i 番目のクエリに対する答えは、mi 以下の nums の要素の中から選んだ任意の要素と xi のビット単位 XOR の最大値です。もし nums のすべての要素が mi より大きければ、その答えは -1 となります。 最終的には、queries と同じ長さの配列 answer を返す必要があります。answer[i] には i 番目のクエリの答えを格納してください。 入力例と出力例 例として、入力が nums = [0,1,