离散化——化不可能为可能(STL)

所谓离散,就是化连续为不连续,使得我们某种枚举的方法得以实现。

当然,离散还能够帮助我们将某些数据范围很大达到2^16,但是这些数据并不多(例如才1000+),我们可以把数据进行离散,保持他们之间的相对大小。

例如这里有几个数:4865845,146384512,598745,896561634,4865845

我们先对数进行排序:598745,4865845,4865845,146384512,896561634

离散后就变成了:0,1,1,2,3(1,2,2,3,4也行)

我们不仅可以将很大的数据进行离散,对于要整型数据结构的,但我们操作的数据是小数的,我们也可以对其进行离散。

因此在这里 离散就是维护他们的相对大小,当然,保留原来的数据,我们可以将离散后的值和离散前的值进行相互映射。

离散的主要步骤:

1.排序

2.去重

3.离散

这里我们可以运用STL,从而实现代码短,易编写。

假设我们有三个数据:a[n],b[n],rank[n];(其中a[n]为将要离散的数组,b[n]为a[n]的备份,rank[n]用于排序后去重提供离散化的值(排名),n为数据个数)

sort(rank,rank+n);//先从小到大排序
int size=unique(rank,rank+n)-rank;//unique函数可去掉连续重复的字母,其中返回值是rank数组去重后实际最后一个数字的地址(具体可以百度一下)-rank中的rank指的是rank[0]的地址,可以联想快排里面rank+n的用法 这里size就是去重后数组的长度
for(int i=0;i<n;i++)
a[i]=lower_bound(rank,rank+size,a[i])-rank;//lower_bound返回第1个不小于a[i]的值的指针,离散后序列为0, 1, 2, ..., size - 1,如果想要1,2,3,...,size的话就+1或者用upper_bound,upper_bound返回第1个大于a[i]的值的指针


如果数组是从1开始的而不是0的话 只需要将rank改为(rank+1) 即
sort(rank+1,rank+n+1);
int size=unique(rank,rank+n)-(rank+1);
for(int i=0;i<n;i++)
a[i]=lower_bound(rank,rank+size,a[i])-(rank+1);

  关于离散化后查询的问题

1.离散后的值为x,那么离散前的值就是rank[x];

2.离散前的下标为i,那么对应的离散后的值是a[i];

3.离散前的值为x,那么根据上面离散的方法即可求得离散后的值就是a[lower_bound(rank,rank+size,x)-rank]

 

离散是一种思想,有时候会有意想不到的效果。

posted @ 2017-08-02 19:20  ~Lanly~  阅读(443)  评论(0编辑  收藏  举报