离散化

离散化

1.第一种离散化

这个是分三步操作

  1. 先用一个b数组把原数组存起来

  2. 对b数组进行排序去重

  3. 然后找原数组在b的位置

这个思想因该很简单

#include<iostream>
#include<algorithm>
using namespace std;
int a[1000100],b[1000100];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
int tot=unique(b+1,b+1+n)-b-1;//去重后的元素个数
for(int i=1;i<=n;i++){
a[i]=lower_bound(b+1,b+1+tot,a[i])-b;//求出a[i]是第几大的
}
for(int i=1;i<=n;i++){
cout<<a[i]<<' ';
}
return 0;
}

比如说数据{6,8,8,9,9,4,5}经过b数组{4,5,6,8,9}之后就变成了{3,4,4,5,1,2,}就缩小了数组范围

可以去重但是效率可能略低一点

2.第二种离散化(去重比较麻烦)

这个就是开个结构体保存值和第几个输入的,然后排序后则可以再次赋上新值

#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int v,id;
bool operator<(const node &x)const{
return v<x.v;
}
}a[100010];
int rk[100010];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].v;
a[i].id=i;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
rk[a[i].id]=i;
}
for(int i=1;i<=n;i++){
cout<<rk[i]<<' ';
}
return 0;
}

 

画个表表示一下

 12345
a.v 6 8 9 4 5
a.id 1 2 3 4 5
排序后          
a.v 4 5 6 8 9
a.id 4 5 1 2 3
rk rk[4]=1 rk[5]=2 rk[1]=3 rk[2]=4 rk[3]=5
最后输出          
rk 3 4 5 1 2

这个rk数组就是离散化后的a数组但是范围变成了1-5.

3.第三种方法

nums.erase(unique(nums.begin(), nums.end()),nums.end()) ;
查找元素离散化的值就直接用这个函数就可以了
return lower_bound(nums.begin(), nums.end(),x) - nums.begin() + 1 ;//下标从一开始。

为什么可以这样子呢?搜索一下好吧

image-20220718144722491

unique的去重方式是把相同元素移动到数组的最后面。最后将指针移动到不重复的元素的那个位置上。所以再用个erase就可以擦掉所有重复元素即可。

image-20220718145021603

unique是假的去除。他只会像上面那样操作。

 
posted @   silky__player  阅读(322)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示