离散化 笔记与思路整理

之前写到树状数组求逆序对的时候提到了大数据需要离散化的处理。今天整理一下离散化的方法。

首先,离散化用于处理的数据具有以下特点:

1、很大或有负数,但数据量不是很大;

2、只需要大小关系,而具体数值没有意义。

因此,用离散化处理后的数据大小关系不变,但是更利于计算,尤其是类似于桶排序的需要将数据变为数组下标的操作。例如,数组 {122136, 0, -12, 1, 4} 离散化后为 {5, 2, 1, 3, 4} 。

一、利用STL

1、对原序列进行排序;

2、去掉重复的元素,以保证相同元素离散化后结果相同;

3、原数组中的每个数现在在数组中的位置即为离散化后的值。

代码实现:

//a[]为原数组,t[]为临时数组,n为元素个数 
void dsc(){
    memcpy(t, a, n * sizeof(int)); //复制数组到临时数组
    sort(t, t+n); //升序排序
    int len = unique(t, t+n) - t - 1; //去重,len为去重后数组长度
    for(int i=0; i<n; i++){
        a[i] = lower_bound(t, t+len, a[i]) - t; //找到a[i]位置
    }
}

二、结构体存储

1、使用结构体储存每个元素的值与位置;

2、以值为关键字排序;

3、循环赋值,遇到相邻相同值不变即可;

4、如果需要,以位置为关键字排序恢复原位置。

代码实现:

struct node{
    int val, pos;
} a[maxn]; //存储值与位置
bool cmp(const node &a, const node &b){
    return a.val < b.val;
} //以值为关键字排序
void dsc(){
    sort(a, a+n, cmp);
    int curr = 0, cnt = -1; //-1是为了使第一项为0
    while(curr < n){
        if(a[curr+1].val == a[curr].val) cnt --; //相同值元素离散化后也相同
        a[curr].val = ++ cnt;
        curr ++;
    }
    //sort(a, a+n, cmp_based_on_position); //恢复顺序
}
原文地址:https://www.cnblogs.com/miserweyte/p/11588103.html