离散化本质上可以看成是一种 哈希,其保证数据在哈希以后仍然保持原来的顺序关系。
通俗地讲,就是当有些数据因为本身很大或者类型不支持,自身无法作为数组的下标来方便地处理,而影响最终结果的只有元素之间的相对大小关系时,我们可以将原来的数据按照从大到小编号来处理问题,即离散化。
通俗地讲,就是把无穷大集合中的若干个元素映射为有限集合以便于统计。
离散化数组
我们可以把a数组排序并去掉重复的数值,得到有序数组b[1]~b[m],在b数组的下标i与数值b[i]之间建立映射关系。若要查询整数i(1<=i<=m)代替的数值,只需直接返回b[i]若要查询整数a[j](1<=j<=n)被哪个1~m之间的整数代替,只需在数组b中二分查找a[j]的位置即可
void discreate(){sort(a + 1, a + n + 1);for (int i = 1; i <= n; i++)if (i == 1 || a[i] != a[i - 1])b[++m] = a[i];}int query(int x){return lower_bound(b + 1, b + m + 1, x) - b;}
#include <bits/stdc++.h>using namespace std;int a[110], b[110], n, m;vector<int> A;void discreate(){sort(a + 1, a + n + 1);for (int i = 1; i <= n; i++)if (i == 1 || a[i] != a[i - 1])b[++m] = a[i];}int query(int x){return lower_bound(b + 1, b + m + 1, x) - b;}int main(){cin >> n;for (int i = 1; i <= n; i++){cin >> a[i];}discreate();for (int i = 1; i <= n; i++) cout << query(a[i]) << ' ';puts("");return 0;}
离散化vector
同样地,我们也可以对 vector 进行离散化:
// a[i]是原数组,b[i]存储离散化新的编号#include <bits/stdc++.h>using namespace std;int a[110], b[110], n;vector<int> A;int main(){cin >> n;for (int i = 0; i < n; i++){cin >> a[i];A.push_back(a[i]);}sort(A.begin(), A.end());A.erase(unique(A.begin(), A.end()), A.end());for (int i = 0; i < n; i++)b[i] = lower_bound(A.begin(), A.end(), a[i]) - A.begin();for (int i = 0; i < n; i++) cout << b[i] << ' ';puts("");return 0;}
