Catalog
  1. 1. ·什么是离散化?
  2. 2. ·为什么要用、什么时候要用离散化呢?
  3. 3. ·我们怎么去实现离散化呢?
  4. 4. ·具体该怎么用代码实现呢?
    1. 4.1. unique
      1. 4.1.1. cnt = unique(a + 1, a + n + 1) - a - 1
    2. 4.2. lower_bound
      1. 4.2.1. ans = lower_bound(a + 1, a + n + 1, b) - a;
离散化-学习

·什么是离散化?

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

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

如果让你吧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;
}
Author: wflight
Link: http://yoursite.com/2019/08/02/离散化-学习/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶

Comment