简介

离散化本质上可以看成是一种 哈希 ,其保证数据在哈希以后仍然保持原来的全/偏序关系。

通俗地讲,就是当我们只关心数据的大小关系时,用排名代替原数据进行处理的一种预处理方法。离散化本质上是一种哈希,它在保持原序列大小关系的前提下把其映射成正整数。当原数据很大或含有负数、小数时,难以表示为数组下标,一些算法和数据结构(如BIT)无法运作,这时我们就可以考虑将其离散化。

用来离散化的可以是大整数、浮点数、字符串……等等。

实现

C++ 离散化有现成的 STL 算法:

离散化数组

将一个数组离散化,并进行查询是比较常用的应用场景:

// a[i] 为初始数组,下标范围为 [1, n]
// len 为离散化后数组的有效长度
std::sort(a + 1, a + 1 + n);
len = std::unique(a + 1, a + n + 1) - a -
1; // 离散化整个数组的同时求出离散化后本质不同数的个数。

在完成上述离散化之后可以使用 std::lower_bound 函数查找离散化之后的排名(即新编号):

std::lower_bound(a + 1, a + len + 1, x) - a;  // 查询 x 离散化后对应的编号

同样地,我们也可以对 vector 进行离散化:

// std::vector<int> a, b; // b 是 a 的一个副本
std::sort(a.begin(), a.end());
a.erase(std::unique(a.begin(), a.end()), a.end());
for (int i = 0; i < n; ++i)
b[i] = std::lower_bound(a.begin(), a.end(), b[i]) - a.begin();

实际演示:

现在我们有序列 A=[10, 23, 35, 3, -40, 3] 。我们先复制一个同样的序列:

int C[N];
memcpy(C, A, sizeof(A));

排序,去重:

sort(C, C + n);
int l = unique(C, C + n) - C; // l为不重复元素的数量

std::unique()的返回值是一个迭代器(对于数组来说就是指针了),它表示去重后容器中不重复序列的最后一个元素的下一个元素。所以可以这样作差求得不重复元素的数量。现在我们有C=[-40, 3, 10, 23, 35]。

再用一个数组,储存A中每个元素在C中的排名:

int L[MAXN];
for (int i = 0; i < n; ++i)
L[i] = lower_bound(C, C + l, A[i]) - C + 1; // 二分查找

这样我们就实现了原序列的离散化。得到 L=[3, 4, 5, 2, 1, 2]

因为排序和n次二分查找的复杂度都是 \(\mathcal{O}(n\ log\ n)\) ,所以离散化的复杂度也是 \(\mathcal{O}(n\ log\ n)\) 。完整代码很短:

int C[N], L[N];
// 在main函数中...
memcpy(C, A, sizeof(A)); // 复制
sort(C, C + n); // 排序
int l = unique(C, C + n) - C; // 去重
for (int i = 0; i < n; ++i)
L[i] = lower_bound(C, C + l, A[i]) - C + 1; // 查找

离散化也不一定要从小到大排序,有时候也需要从大到小。这时在排序和查找时相应地加上greater<int>()就可以了。

什么是离散化?C++实现方法的更多相关文章

  1. ACM/ICPC 之 数据结构-线段树+区间离散化(POJ2528)

    这道题用线段树做更方便更新和查询,但是其数据范围很大,因此要将离散化和线段树结合起来,算是一道比较经典的线段树+离散化的例题. 线段树的离散化有很多方法,在这里,我先用一次结点离散化,间接将源左右端点 ...

  2. 【POJ】2528 Mayor's posters ——离散化+线段树

    Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K   Description The citizens of Bytetown, A ...

  3. 数据预处理 | 使用 Pandas 进行数值型数据的 标准化 归一化 离散化 二值化

    1 标准化 & 归一化 导包和数据 import numpy as np from sklearn import preprocessing data = np.loadtxt('data.t ...

  4. 【转】用深度学习做crowd density estimation

    本博文主要是CVPR2016的<Single-Image Crowd Counting via Multi-Column Convolutional Neural Network>这篇文章 ...

  5. Codeforces 980D

    这题其实挺水的,但我比较vegetable,交了好多次才过. 题意: 给定一个序列,把这个序列的所有连续子序列分组,每组中任意两个数相乘是个完全平方数,输出每个子序列最少分的组数: 思路: 先把每个数 ...

  6. 树状数组(BIT)—— 一篇就够了

    树状数组(BIT)-- 一篇就够了 前言.内容梗概 本文旨在讲解: 树状数组的原理(起源,原理,模板代码与需要注意的一些知识点) 树状数组的优势,缺点,与比较(eg:线段树) 树状数组的经典例题及其技 ...

  7. PID参数

    大家奉上一篇关于PID算法及参数整定的知识! 1.位置表达式 位置式表达式是指任一时刻PID控制器输出的调节量的表达式. PID控制的表达式为 式中的y(t)为时刻t控制器输出的控制量,式中的y(0) ...

  8. DS

    树状数组 原始问题 \(a_x \overset+\gets y\) \(\sum\limits_{i=1}^{r} a_i\) 解决方法: 定义 \({\rm lb}(i) = i-i \wedge ...

  9. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  10. WOE:信用评分卡模型中的变量离散化方法(生存分析)

    WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...

随机推荐

  1. 【Android】如何去掉默认标题栏

    1.在AndroidManifest.xml文件中修改并添加以下代码 android:theme="@style/Theme.AppCompat.NoActionBar" 2.在你 ...

  2. 深度解析C#中LinkedList<T>的存储结构

    本文承接前面的3篇有关C#的数据结构分析的文章,对于C#有关数据结构分析还有一篇就要暂时结束了,这个系列主要从Array.List.Dictionary.LinkedList. SortedSet等5 ...

  3. Chrome扩展的核心:manifest 文件(上)

    大家好,我是dom哥.我正在写关于 Chrome 扩展开发的系列文章,感兴趣的可以点个小星星. Chrome 在全球浏览器市场份额独占 6 成,无论是对普通用户还是开发者,都是电脑里的必备利器.Chr ...

  4. 11 HTTP的特点,优点和缺点

    [toc] # HTTP的五大特点 # HTTP的优点 1.  最大的优点:简单.灵活和易于拓展 2. 拥有成熟的软硬件环境,应用的非常广泛,是互联网的基础设施 3. 是无状态的,可以轻松实现集群化, ...

  5. 大模型那么火,教你一键Modelarts玩转开源LlaMA(羊驼)大模型

    本文分享自华为云社区<大模型那么火,教你一键Modelarts玩转开源LlaMA(羊驼)大模型>,作者:码上开花_Lancer . 近日, LlaMA(羊驼)这个大模型再次冲上热搜! LL ...

  6. EEPROM M24C64替换AT24C64出现读取数据为0xff情况解决办法

    EEPROM M24C64替换AT24C64出现读取数据为0xff情况解决办法 硬件情况 STM32F103CBT6+模拟IIC,主频72MHz,IIC上拉电阻3.3kΩ 出现原因 在IIC停止信号上 ...

  7. 【源码系列#05】Vue3响应式原理(Ref)

    Ref & ShallowRef ref:接受一个参数值并返回一个响应式且可改变的 ref 对象.ref 对象拥有一个指向内部值的单一属性 .value 可以将 ref 看成 reactive ...

  8. Windows Server 2019/2016 配置自动更新和更换大陆更新服务器

    文章原地址: 运行 > gpedit.msc -> 计算机配置 -> 管理模板 -> Windows 组件 -> Windows 更新 下面中右侧三个选项是本篇教程中会介 ...

  9. 云MSP服务案例丨某知名制造集团的Oracle RAC部署实践

    简介: 随着DT时代到来,移动互联网.物联网开始高速发展,更多的企业意识到了数据库架构选型对业务发展的重要性,如何管理和利用好数据已经变得越来越重要.Oracle作为世界上目前最流行的关系型数据库管理 ...

  10. kubernetes之部署springboot项目jar项目(三)

    kubernetes之部署war项目(三) k8s系列 源自我工作上的实际场景,记录于此. k8s部署springboot项目 假设我的jar项目是:myjar.jar 用到的环境 centos 7. ...