数値のリストが与えられた場合、場合によっては、これらの数値の値の絶対的な大きさは重要ではなく、相対的な大きさが重要です。たとえば、クラスのスコアは 99 98 97 95 96 で、ランキングは 1 2 3 5 4 です。
離散化は、アルゴリズムをより高速かつ省スペースで処理できるように、広く分散したデータとまばらに分散したデータを密な分布に変換するデータ処理技術です。
離散化ステップ: ソート、離散化、ホーミング。
例: 4000 210 11 45 800
配列の添字は 1 2 3 4 5 です
それらを構造体に格納し、並べ替えます。
---------------------
並べ替え: 11 45 210 800 4000
3 4 2 5 1
------------------------
離散化: 1 2 3 4 5
配列の添字: 3 4 2 5 1
------------------------
ホーミング: 5 3 1 2 4
配列インデックス 1 2 3 4 5
コード分析は次のとおりです。
#define _CRT_SECURE_NO_WARNINGS 1
//离散化
#include<bits/stdc++.h>
using namespace std;
const int N = 500010;
struct data1 {
int val;
int id; // 用坐标代替
}olda[N];
int newa[N];
bool cmp(data1 x, data1 y) { return x.val < y.val; }
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &olda[i].val);
olda[i].id = i;
}
sort(olda + 1, olda + 1 + n, cmp); //排序
//离散化 + 归位
for (int i = 1; i <= n; i++) {
newa[olda[i].id] = i;
if (olda[i].val == olda[i - 1].val)
newa[olda[i].id] = newa[olda[i - 1].id];
}
for (int i = 1; i <= n; i++)
printf("%d", newa[i]);
return 0;
}
離散化は STL 関数を使用して実現されます。
lower_bound() 関数と unique() 関数は離散化を実装します。
x 以上の最初の要素を検索します: lower_bound() かつ x に等しい。pos = lower_bound(a,a+n,x) - a のような位置。
unique() 関数:
Unique は、C++ 標準テンプレート ライブラリ STL の非常に便利な関数の 1 つです。この関数を使用するには、 #include <algorithm> ヘッダー ファイルが必要です
この関数の機能は、コンテナまたは配列内の隣接する要素の繰り返し要素を「削除」することです
(1) ここでの削除は実際の消去ではなく、繰り返し要素をコンテナの最後に配置し、戻り値を返します。は重複排除後の の末尾アドレスです。
これは隣接する要素に対してのみ機能することに注意してください。
(2) Unique は隣接する要素を対象としているため、順序が乱れている配列メンバーまたはコンテナー メンバーについては、最初に並べ替える必要があり、std::sort() 関数を呼び出すことができます。
#define _CRT_SECURE_NO_WARNINGS 1
//离散化
#include<bits/stdc++.h>
using namespace std;
const int N = 5000010;
int olda[N];
int newa[N];
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &olda[i]);
newa[i] = olda[i]; //这一步很关键
}
sort(olda + 1, olda + n + 1);//默认是从小到大 less<int>()
int cnt = n; // 记录个数 调用unique函数时,是去重的数组
//cnt = unique(olda + 1, olda + 1 + n) - (olda + 1);//返回不重复的尾元素 如 1 1 2 3 调用函数后 1 2 3 1 返回 3
for (int i = 1; i <= cnt; i++) {
newa[i] = lower_bound(olda + 1, olda + 1 + n, newa[i]) - olda;
}
for (int i = 1; i <= cnt; i++) {
printf("%d ", newa[i]);
}
return 0;
}