1.方法一
使用unique()函数
功能:主要实现对一个数组的数进行去重。
其实是该函数是把相邻重复的元素中的一个扔到后面。
返回值为去重之后最后一个不重复元素的下一个位置的迭代器,类型为相对应的地址类型。
关键代码:
离散化之后a数组存的是原来数的大小排名,也是b中该数的下标
//b数组用来存放去重后的数据
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i];//先赋值
}
//必须先排序
sort(b + 1, b + 1 + n);//unique 和 lower_bound都需要有序序列
ll len = unique(b + 1, b + 1 + n) - b-1; //记录b数组去重后的长度
for (int i = 1; i <= n; i++)
a[i] = lower_bound(b + 1, b + len, a[i]) - b;
//离散化 利用二分查找 快速重新赋值
流程图:
测试代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 1e3+5;
ll a[maxn], b[maxn];
ll n;
void solve()
{
//b数组用来存放去重后的数据
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i];//先赋值
}
//必须先排序
sort(b + 1, b + 1 + n);//unique 和 lower_bound都需要有序序列
ll len = unique(b + 1, b + 1 + n) - b-1; //记录b数组去重后的长度
for (int i = 1; i <= n; i++)
a[i] = lower_bound(b + 1, b + len, a[i]) - b;
//离散化 利用二分查找 快速重新赋值
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
}
int main()
{
n = 10;
for(int i=1;i<=n;i++)
{
cin>>a[i];cout<<a[i]<<" ";
}
cout<<'\n';
solve();
return 0;
}
输入:
6 4 2 8 74 7 6 2 4 12
输出:
6 4 2 8 74 7 6 2 4 12
3 2 1 5 7 4 3 1 2 6
2.方法二
使用二元组,可以是结构体,也可以是pair
设置一个辅助数组
h
[
N
]
h[N]
h[N]
以5,6,4,3,1举例
p[i].first(val)
5 6 4 3 1p[i].second(id)
1 2 3 4 5
排序后
p[i].first
1 3 4 5 6
p[i].second
5 4 3 1 2
id(数组的下标)
1 2 3 4 5 (这就是新的离散化后的值,需要存起来)
使用辅助数组h[],
h [ p [ i ] . s e ] = i h[p[i].se] = i h[p[i].se]=i即为相应存值操作
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 1e5+5;
pii p[N];
int n,h[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>p[i].fi;
p[i].se = i;
}
sort(p+1,p+1+n);
for(int i=1;i<=n;i++)
h[p[i].se] = i;
for(int i=1;i<=n;i++)
cout<<h[i]<<' ';
return 0;
}