离散化

1. 离散化的目的

值域压缩:把无限空间中有限的个体映射到有限的空间中区,以提高算法的时空效率

当原数组中的数字很大、负数、小数时(大多数情况下是数字很大),难以将“元素值”表示为“数组下标”,一些依靠下标实现的算法和数据结构无法实现时,我们就可以考虑将其离散化。

简而言之:将稀疏离散化简为稠密连续的一段

离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。

2. 实现方式

数组离散化:

// arr[i] 为原数组
for(int i = 1; i <= n; i ++ ) tmp[i] = arr[i];
// 排序
sort(tmp + 1, tmp + n + 1);
// 去重:放回一个迭代器,指向去重后不重复序列的最后一个元素下标
int len = unique(tmp + 1, tmp + n + 1) - (tmp + 1);
// lower_bound 查找大于等于 a[i] 的第一个数的下标
for(int i = 1; i <= n; i ++ )
    arr[i] = lower_bound(tmp + 1, tmp + len + 1, arr[i]) - tmp;

vector 离散化:

// std::vector<int> arr;
std::vector<int> tmp(arr);  // tmp 是 arr 的一个副本
std::sort(tmp.begin(), tmp.end());
tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
for (int i = 0; i < n; ++i)
  arr[i] = std::lower_bound(tmp.begin(), tmp.end(), arr[i]) - tmp.begin();

3. 示例代码

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 9;
int a[N];

vector<int> L;
int getidx(int x)
{
    return lower_bound(L.begin(), L.end(), x) - L.begin();
}

int main()
{
    int n; cin >> n;
    for(int i = 1; i <= n; i ++ ) cin >> a[i];
    for(int i = 1; i <= n; i ++ ) L.push_back(a[i]);
    
    sort(L.begin(), L.end());
    L.erase(unique(L.begin(), L.end()), L.end());
    
    cout << "离散化数组为:"
    for(const auto &i : L) cout << i << ' ';
    cout << endl;
    
    int val; cin >> val;
    cout << getidx(val) << endl;
    
    return 0;
}

南池北塘
1 声望0 粉丝

« 上一篇
【算法】差分
下一篇 »
【算法】贪心