离散化本质上可以看成是一种 哈希,其保证数据在哈希以后仍然保持原来的顺序关系。

通俗地讲,就是当有些数据因为本身很大或者类型不支持,自身无法作为数组的下标来方便地处理,而影响最终结果的只有元素之间的相对大小关系时,我们可以将原来的数据按照从大到小编号来处理问题,即离散化。

通俗地讲,就是把无穷大集合中的若干个元素映射为有限集合以便于统计。

离散化数组

  1. 我们可以把a数组排序并去掉重复的数值,得到有序数组b[1]~b[m],
  2. b数组的下标i与数值b[i]之间建立映射关系。
  3. 若要查询整数i(1<=i<=m)代替的数值,只需直接返回b[i]
  4. 若要查询整数a[j](1<=j<=n)被哪个1~m之间的整数代替,只需在数组b中二分查找a[j]的位置即可
  1. void discreate(){
  2. sort(a + 1, a + n + 1);
  3. for (int i = 1; i <= n; i++)
  4. if (i == 1 || a[i] != a[i - 1])
  5. b[++m] = a[i];
  6. }
  7. int query(int x){
  8. return lower_bound(b + 1, b + m + 1, x) - b;
  9. }
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int a[110], b[110], n, m;
  4. vector<int> A;
  5. void discreate(){
  6. sort(a + 1, a + n + 1);
  7. for (int i = 1; i <= n; i++)
  8. if (i == 1 || a[i] != a[i - 1])
  9. b[++m] = a[i];
  10. }
  11. int query(int x){
  12. return lower_bound(b + 1, b + m + 1, x) - b;
  13. }
  14. int main(){
  15. cin >> n;
  16. for (int i = 1; i <= n; i++){
  17. cin >> a[i];
  18. }
  19. discreate();
  20. for (int i = 1; i <= n; i++) cout << query(a[i]) << ' ';
  21. puts("");
  22. return 0;
  23. }

离散化vector

同样地,我们也可以对 vector 进行离散化:

  1. // a[i]是原数组,b[i]存储离散化新的编号
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int a[110], b[110], n;
  5. vector<int> A;
  6. int main(){
  7. cin >> n;
  8. for (int i = 0; i < n; i++){
  9. cin >> a[i];
  10. A.push_back(a[i]);
  11. }
  12. sort(A.begin(), A.end());
  13. A.erase(unique(A.begin(), A.end()), A.end());
  14. for (int i = 0; i < n; i++)
  15. b[i] = lower_bound(A.begin(), A.end(), a[i]) - A.begin();
  16. for (int i = 0; i < n; i++) cout << b[i] << ' ';
  17. puts("");
  18. return 0;
  19. }