浅谈离散化

·什么是离散化?

离散化,把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。

·为什么要用、什么时候要用离散化呢?

如果让你吧1000个1到1000的数放到桶里,那么非常简单,直接开一个大小为1000的数组,然后在里面统计就可以了。
但是,如果吧这1000个数的大小改为1到1000000000呢?很显然,直接开一个大小为1000000000的数组去统计是不现实的,直接MLE。这时,我们就需要用到离散化了。(当然,这只是一个小例子)

·我们怎么去实现离散化呢?

对于一个数组a,我们可以用另外一个数组去记录其中每个数的大小关系(如数字b在a中为第k大),这样就可以在新得到的数组中查询每个数的大小关系。这样,我们就达到了离散化的目的。而且,我们可以利用这个大小关系来得到之前原数组对应位置的数字。

·具体该怎么用代码实现呢?

为了实现离散化,我们需要用到unique和lower_bound这两个函数。

unique

unique可以统计某数组中不同元素的个数,如我们想用cnt去记录长度为n的数组a中有几个不同的元素,则可以用到unique,代码为

cnt = unique(a + 1, a + n + 1) - a - 1

lower_bound

其实还有一个叫upper_bound的函数

lower_bound可以返回某个元素在某个数组中是第几大的。
例如,如你想用ans去记录数字b在长度为n数组a中是第几大的,那么就可以通过lower_bound去实现,代码为

ans = lower_bound(a + 1, a + n + 1, b) - a;

附一下完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

int n,cnt,ans,a[1000],b[1000],x[1000];

int mysort(int a,int b) {return a < b;}

int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i]; //输入
for(int i = 1; i <= n; i++) x[i] = a[i]; //用x记录a,方便后续操作
sort(x + 1, x + n + 1, mysort); //排序 对于统计来书可有可无,但方便去重和还原
cnt = unique(x + 1, x + n + 1) - x - 1; //统计x中不同颜色的个数
for(int i = 1; i <= n; i++) b[i] = lower_bound(x + 1, x + n + 1, a[i]) - x; //统计每个元素在原数组的大小位置
cout << "cnt = " << cnt << endl; //查看不同元素的个数
for(int i = 1; i <= n; i++) cout << b[i] << " "; //查看离散化后的数组
cout << endl;
for(int i = 1; i <= n; i++) cout << x[b[i]] << " "; //还原数组a
cout << endl;
return 0;
}
原文地址:https://www.cnblogs.com/aurorapolaris/p/13502484.html