C++で配列内の一意なペア(ユニークペア)の数を求める方法をわかりやすく解説
C++で配列内に存在する一意なペア(ユニークペア)の数を求めるには、適切な考え方と実装方法を理解しておく必要があります。一意なペアの数を数えるとは、与えられた配列から作成できるすべてのペアの中で、重複しないペアだけをカウントすることを意味します。例えば、次のようなケースが挙げられます。
入力 : array[ ] = { 5, 5, 9 }
出力 : 4
説明 : 一意なペアは (5, 5)、(5, 9)、(9, 5)、(9, 9) の4つです。
入力 : array[ ] = { 5, 4, 3, 2, 2 }
出力 : 16解決のためのアプローチ
この問題を解くには、主に2つのアプローチがあります。
1. 全探索(ブルートフォース)アプローチ
この方法では、考えられるすべてのペアを走査してセット(set)に格納し、最後にセットのサイズを取得することで答えを求めます。すべてのペアを生成するためシンプルで分かりやすい反面、計算量は O(n² log n) となり、配列が大きくなると処理に時間がかかる点がデメリットです。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
int main () {
int arr[] = { 5, 4, 3, 2, 2 };
int n = sizeof (arr) / sizeof (arr[0]);
// ペアを格納するためのセットを宣言
set < pair < int, int >>set_of_pairs;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
set_of_pairs.insert (make_pair (arr[i], arr[j]));
int result = set_of_pairs.size();
cout <<"Number of unique pairs : " << result;
return 0;
}出力
Number of unique pairs : 16
コードの解説
このコードでは、まずペアを格納するためのセット変数を宣言します。次に、二重ループを使ってインデックス i と j により考えられるすべてのペアを走査し、それぞれのペアをセットに挿入していきます。セットは重複する要素を自動的に排除してくれるため、最後にセットのサイズを取得すれば、それがそのまま一意なペアの総数になります。
2. 効率的なアプローチ
もう一つの方法は、まず配列内の一意な要素(重複しない値)の数を求めることです。各一意な要素は、自分自身を含む他のすべての一意な要素とペアを作ることができるため、一意なペアの総数は「一意な要素数の2乗」に等しくなります。このアプローチの計算量は O(n) であり、非常に効率的です。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
int main () {
int arr[] = { 5, 4, 3, 2, 2 };
int n = sizeof (arr) / sizeof (arr[0]);
// 一意な要素を格納するセットを宣言
unordered_set < int >set_of_elements;
// 配列の要素をセットに挿入
for (int i = 0; i < n; i++)
set_of_elements.insert (arr[i]);
int size = set_of_elements.size ();
// 一意なペアの数を求める
int result = size * size;
cout << "Number of unique pairs in an array: " << result;
return 0;
}出力
Number of unique pairs : 16
コードの解説
このコードでは、まずセットを宣言し、配列の各要素を順番にセットへ挿入していきます。unordered_set は重複する要素を自動的に取り除くため、セットには一意な値のみが残ります。その後、セットのサイズを取得し、「サイズ × サイズ(n²)」という式から一意なペアの総数を計算して結果を出力しています。
まとめ
本記事では、配列内の一意なペアの数を求める問題について、シンプルな方法と効率的な方法の2つの解き方を解説しました。シンプルな全探索では、すべてのペアをセットに挿入するため計算量は O(n² log n) になりますが、効率的な方法では一意な要素数を求めて2乗するだけで O(n) で答えを得られます。なお、同じプログラムはC言語、Java、Pythonなど他のプログラミング言語でも同様の考え方で実装できます。この記事が皆さんの学習に役立てば幸いです。
-
C++で文字列の部分文字列の総数を求める方法を解説
この記事では、与えられた文字列から作成できる空でない部分文字列の個数を求める方法について解説します。入力 : string = "moon" 出力 : 10 説明 : 部分文字列は m、o、o、n、mo、oo、on、moo、oon、moon の 10 個です。 入力 : string = "yellow" 出力 : 21解法のアプローチ文字列の長さを n とします。上の例からも分かるように、考えられるすべての部分文字列の個数を求めるには、長さ n、(n-1)、(n-2)、(n-3)、……2、1 の部分文字列の個数を順に加算していく必要があります。部分文
-
C++で列車の停車駅の組み合わせ数を求める方法
地点XとYの間にはn個の中間駅があるとします。ここで、「どの2つの停車駅も隣り合わない」という条件のもとで、s個の駅に停車する列車の配置方法が何通りあるかを求める問題を考えてみましょう。この記事では、停車駅の組み合わせ数を求めるためのアプローチを段階的に詳しく解説します。この問題は、本質的には組合せ論の問題であり、s個の停車駅の選び方の総数を求めることになります。 問題を解くアプローチ まず具体例として、中間駅が8個あり、そのうち3個の駅に停車させたい場合を考えてみます。 n = 8, s = 3 このとき、列車が停車できない駅は(n − s)、つまり5個残ることになります。 停車できない