C++のSTLに含まれるunique関数は、隣接する重複要素を除去するための便利な機能です。この関数は<algorithm>ヘッダファイルに定義されており、配列やコンテナ内の連続した重複データを効率的に処理できます。
unique関数の動作原理
unique関数はソート済みのデータに対して最も効果を発揮します。この関数は重複要素を物理的に削除するのではなく、重複する要素を配列の後方に移動させ、ユニークな要素列の終端を示すイテレータを返します。
例えば、以下の配列を考えます:
| インデックス | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|---|---|---|---|---|---|---|---|
| 値 | 1 | 3 | 3 | 2 | 5 | 4 | 4 |
unique関数を適用すると、重複要素が配列末尾に移動し、先頭からユニークな要素が並びます。
戻り値と配列長の計算
unique関数の典型的な使用方法は以下の通りです:
#include <bits/stdc++.h>
using namespace std;
int main() {
int data[] = {1, 3, 3, 2, 5, 4, 4};
int size = sizeof(data) / sizeof(data[0]);
// unique関数の戻り値はイテレータ
int* end_ptr = unique(data, data + size);
// ユニークな要素数を計算
int unique_count = end_ptr - data;
cout << "ユニークな要素数: " << unique_count << endl;
// 結果の出力
for(int i = 0; i < unique_count; i++) {
cout << data[i] << " ";
}
return 0;
}
このコードでは、unique(data, data + size)が返すポインタから配列先頭のポインタを引くことで、実際にユニークな要素の個数を求めています。
実用的な応用例
実際の開発では、unique関数を使用する前にソートを行うことが一般的です。これにより、完全にソートされた状態で重複排除が可能になります:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> numbers = {7, 2, 3, 2, 5, 3, 7, 1, 5};
// ソート処理
sort(numbers.begin(), numbers.end());
// 重複削除
auto new_end = unique(numbers.begin(), numbers.end());
// コンテナのサイズ調整
numbers.erase(new_end, numbers.end());
// 結果表示
for(const auto& value : numbers) {
cout << value << " ";
}
return 0;
}
このように、sort関数と組み合わせることで、順序付けられたユニークなデータ集合を得ることができます。