C++で配列内のab=cdとなるすべてのペア(a, b)と(c, d)を見つける方法
配列Aが与えられたとき、その中から積が等しくなる2つのペア(a, b)と(c, d)、つまりab = cdを満たす組み合わせを見つける問題を考えます。
例えば、配列A = [3, 4, 7, 1, 2, 9, 8]の場合、(4, 2)と(1, 8)というペアが条件を満たします。実際に4×2 = 8、1×8 = 8となり、積が一致していますね。
この問題を効率的に解くには、ハッシュテーブル(C++ではunordered_map)を活用します。すべてのペアの積を順に計算し、同じ積がすでにハッシュテーブルに登録されているかどうかを確認することで、条件を満たすペアを検出できます。
アルゴリズムの手順
- iを0からn-1までループさせる
- その内部でjをi+1からn-1までループさせる
- 積 prod = arr[i] × arr[j] を計算する
- prodがハッシュテーブルに存在しない場合、Hash[prod] = (i, j) として登録する
- prodがすでに存在する場合、登録済みのペアと現在のペアを出力する
この方法により、全ペアを総当たりで比較するO(n⁴)の素朴な手法と比べて、大幅に効率化できます。
C++による実装例
#include <iostream>
#include <unordered_map>
using namespace std;
void displayPairs(int arr[], int n) {
bool found = false;
unordered_map<int, pair<int, int>> Hash;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int prod = arr[i] * arr[j];
if (Hash.find(prod) == Hash.end())
Hash[prod] = make_pair(i, j);
else {
pair<int, int> pp = Hash[prod];
cout << "(" << arr[pp.first] << ", " << arr[pp.second]
<< ") and (" << arr[i] << ", " << arr[j] << ")" << endl;
found = true;
}
}
}
if (found == false)
cout << "No pairs have Found" << endl;
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
int n = sizeof(arr) / sizeof(int);
displayPairs(arr, n);
}コードの解説
- unordered_map<int, pair<int, int>>:積(int)をキーとして、それを構成する要素のインデックスペア(pair<int, int>)を値として格納します。
- Hash.find(prod) == Hash.end():同じ積がまだ登録されていないかを判定し、未登録なら新規登録します。
- foundフラグ:条件を満たすペアが1つも見つからなかった場合に、その旨を出力するために使用しています。
実行結果
(1, 6) and (2, 3) (1, 8) and (2, 4) (2, 6) and (3, 4) (3, 8) and (4, 6)
出力を見ると、例えば(1, 6)と(2, 3)は1×6 = 6、2×3 = 6となり、確かにab = cdを満たしていることが確認できます。
計算量
- 時間計算量:O(n²) — すべてのペア(i, j)を一度ずつ調べるためです。
- 空間計算量:O(n²) — 最悪の場合、すべてのペアの積をハッシュテーブルに格納する必要があるためです。
このように、ハッシュテーブルを利用することで、積が一致するペアを効率的に検出できます。配列の要素数が大きくなっても、素朴な総当たり法よりはるかに実用的なアプローチです。
-
C++で最初の配列に存在し、2番目の配列には存在しない要素を検索する方法
概要2つの配列AとBが与えられたとき、配列Aには存在するが配列Bには存在しない要素をすべて見つける方法を解説します。AとBをそれぞれ集合(セット)とみなすと、この操作は「差集合(Set Difference)」の計算に相当します。C++では、標準ライブラリの std::set_difference アルゴリズムを使うことで、この差集合を簡単かつ効率的に求めることができます。set_differenceを使う際のポイントstd::set_difference は <algorithm> ヘッダで定義されているアルゴリズムです。使用する際は、以下の点に注意しましょう。入力となる両方の範
-
C++で配列内の a % b = k を満たすすべてのペア(a, b)を検索する方法
問題の概要配列 A が与えられたとき、その中から a % b = k を満たすすべてのペア(a, b)を見つけることを考えます。たとえば、配列 A = [2, 3, 4, 5, 7]、k = 3 の場合、条件を満たすペアは (7, 4)、(3, 4)、(3, 5)、(3, 7) となります。ここで注意したいのは、(a, b) が順序付きペアであるという点です。つまり (3, 4) と (4, 3) は別々の候補として扱われ、それぞれ剰余演算の結果が k と一致するかどうかが個別に判定されます。解法のアプローチこの問題は、ブルートフォース(総当たり)法によって解くことができます。手順は以下のとお