离散化初接触

本文深入探讨了离散化技术,一种将无限空间中的个体映射到有限空间以提升算法效率的方法。通过排序、去重及索引映射三个步骤,实现数据的有效压缩,特别介绍了STL库中sort、unique和lower_bound函数的应用。

离散化:
不改变数据相对大小的情况下,对数据进行相应的缩小。
学术化一点: 把无限空间中有限的个体(有很多重复元素)映射到有限的空间中去,以此提高算法的时空效率。
例如 4 3 9 1000000 1000000000
可以映射成 2 1 3 4 5

利用STL离散化
思路是:先排序,再删除重复元素,最后索引元素离散化对应的值。
假定待离散化的的序列为a[n],b[n]是a[n]的一次遍历,对应以上三步
sort(b+1,b+1+n);
int len=unique(b+1,b+1+n)-b-1;//len是离散化之后元素的个数(删除重复元素)
for(i=1 ; i<=n ; i++ ) a[i]=lower_bound(b+1 , b+len+1 , a[i] ) - b ;//a[i]为离散化之后对应的数组

unique函数 (详解 添加链接描述
unique(数组首元素地址,数组末地址) - 数组首元素地址

/**/
#include<stdio.h>
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
ll a[1000010],b[1000010],sum[1000010];
int main()
{
    int i,len,n;
    int a[20];
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        printf("%d\n",n);
        for(i=1;i<=n;i++)
        {
            printf("%d ",a[i]);
        }
        printf("\n");
        sort(a+1,a+1+n);
        int len=unique(a+1,a+1+n)-a-1;
        printf("%d\n",len);
        for(i=1;i<=len;i++)
        {
            printf("%d ",a[i]);
        }
        printf("\n");
    }
    return 0;
}

输出
    10
    4 4 5 9 2 5 8 1 1 9//原始a[i]
    6
    1 2 4 5 8 9//unique后的a[i]

lower_bound函数(详解添加链接描述
lower_bound( begin,end,num)-num:从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

    代码:
#include<bits/stdc++.h>
using namespace std;
#define N 10000
int a[N],b[N];
int main()
{
    int i,n;
    scanf("%d",&n);
    for(i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        b[i]=a[i];//去重后会改变a数组元素,所以一开始先让b存一遍a
    }
    printf("%d\n",n);
    for(i=1;i<=n;i++)
        printf("%d ",a[i]);
        printf("\n");
    sort(a+1,a+n+1);//排序后才能去重
    int len=unique(a+1,a+n+1)-a-1;//unique去重,使a[i]大小与下标i对应,并得到去重后的长度
    printf("%d\n",len);
    for(i=1;i<=len;i++)
    printf("%d ",a[i]);
    printf("\n");
    for(i=1; i<=n; i++)
        b[i]=lower_bound(a+1,a+1+len,b[i])-a;//把b[i]放在去重排序后的a序列里面去比,找到最后一个不比b[i]小的元素并返回该元素下标i,所以数组b对应未去重时的序列的元素是第几小
        printf("%d\n",n);
    for(i=1; i<=n; i++)printf("%d ",b[i]);
}

输入
10
5 6 8 4 5 8 4 1 3 6
输出
10
5 6 8 4 5 8 4 1 3 6
6
1 3 4 5 6 8//unique后的a[i]
10
10 4 5 6 3 4 6 3 1 2 5//lower_bound后的b[i]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值