离散化模板
离散化就是把较大的数映射成较小的数。
题⽬描述:定 n 个数,离散化之后,输出每⼀个数离散化之后的值。
测试数据:
10 1999999 12 1999999-48444 568 12-100-2845630 100000001 263
// 输出 7 4 7 2 6 4 3 1 8 5
代码:
#include <iostream>
#include <algorithm>
using namespace std;const int N = 1e5 + 10; // 定义常量N为100010,作为数组最大长度
int n; // 数据元素个数
int a[N]; // 原始数据数组int pos; // 离散化数组的当前位置/长度
int disc[N]; // 用于离散化的临时数组
// 二分查找函数:在离散化数组disc中查找x的位置。大于等于。
int find(int x)
{
int l = 1, r = pos;
while(l < r)
{
int mid = (l+r)/2; // 计算中间位置
if (disc[mid] >= x) // 如果中间值大于等于x
r = mid; // 调整右边界
else
l = mid+1; // 调整左边界
}
return l; // 返回x在disc中的位置
}
int main()
{
cin >> n; // 输入数据个数
// 读取原始数据并复制到离散化数组
for (int i = 1; i <= n; i++)
{
cin >> a[i];
disc[++pos] = a[i]; // 将数据存入离散化数组,pos自增
}
// 对离散化数组进行排序
sort(disc+1, disc+1+pos);
// 去除离散化数组中的重复元素,并更新pos为不重复元素的数量
pos = unique(disc+1, disc+1+pos) - (disc+1);
// unique()函数的作用
// unique(disc+1, disc+1+pos)对数组 disc从索引1到pos的部分进行去重
// unique()函数会将相邻的重复元素移动到数组末尾,并返回指向第一个重复元素的迭代器(指针)
// 注意:unique()只去除相邻的重复元素,这就是为什么需要先排序
// 指针运算
// 指向重复的指针减去第一个指针 ==> 不重复的元素的数量
// 输出每个原始数据离散化后的值:用二分查找
for (int i = 1; i <= n; i++)
{
cout << find(a[i]) << endl;
}
return 0;
}
总代码:
#include <iostream>
#include <algorithm>
using namespace std;const int N = 1e5 + 10; int n;
int a[N]; int pos;
int disc[N]; int find(int x)
{int l = 1, r = pos; while(l < r){int mid = (l+r)/2; if (disc[mid] >= x) r = mid; elsel = mid+1; }return l;
}int main()
{cin >> n; // 读取原始数据并复制到离散化数组for (int i = 1; i <= n; i++){cin >> a[i];disc[++pos] = a[i]; }// 对离散化数组进行排序sort(disc+1, disc+1+pos);pos = unique(disc+1, disc+1+pos) - (disc+1);for (int i = 1; i <= n; i++){cout << find(a[i]) << endl; }return 0;
}
时间复杂度为 O(n log n),适用于大规模数据(如 n ≤ 10^5)
画图很重要哦