什么是离散化?C++实现方法
简介
离散化本质上可以看成是一种 哈希 ,其保证数据在哈希以后仍然保持原来的全/偏序关系。
通俗地讲,就是当我们只关心数据的大小关系时,用排名代替原数据进行处理的一种预处理方法。离散化本质上是一种哈希,它在保持原序列大小关系的前提下把其映射成正整数。当原数据很大或含有负数、小数时,难以表示为数组下标,一些算法和数据结构(如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++实现方法的更多相关文章
- ACM/ICPC 之 数据结构-线段树+区间离散化(POJ2528)
这道题用线段树做更方便更新和查询,但是其数据范围很大,因此要将离散化和线段树结合起来,算是一道比较经典的线段树+离散化的例题. 线段树的离散化有很多方法,在这里,我先用一次结点离散化,间接将源左右端点 ...
- 【POJ】2528 Mayor's posters ——离散化+线段树
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Description The citizens of Bytetown, A ...
- 数据预处理 | 使用 Pandas 进行数值型数据的 标准化 归一化 离散化 二值化
1 标准化 & 归一化 导包和数据 import numpy as np from sklearn import preprocessing data = np.loadtxt('data.t ...
- 【转】用深度学习做crowd density estimation
本博文主要是CVPR2016的<Single-Image Crowd Counting via Multi-Column Convolutional Neural Network>这篇文章 ...
- Codeforces 980D
这题其实挺水的,但我比较vegetable,交了好多次才过. 题意: 给定一个序列,把这个序列的所有连续子序列分组,每组中任意两个数相乘是个完全平方数,输出每个子序列最少分的组数: 思路: 先把每个数 ...
- 树状数组(BIT)—— 一篇就够了
树状数组(BIT)-- 一篇就够了 前言.内容梗概 本文旨在讲解: 树状数组的原理(起源,原理,模板代码与需要注意的一些知识点) 树状数组的优势,缺点,与比较(eg:线段树) 树状数组的经典例题及其技 ...
- PID参数
大家奉上一篇关于PID算法及参数整定的知识! 1.位置表达式 位置式表达式是指任一时刻PID控制器输出的调节量的表达式. PID控制的表达式为 式中的y(t)为时刻t控制器输出的控制量,式中的y(0) ...
- DS
树状数组 原始问题 \(a_x \overset+\gets y\) \(\sum\limits_{i=1}^{r} a_i\) 解决方法: 定义 \({\rm lb}(i) = i-i \wedge ...
- javaSE27天复习总结
JAVA学习总结 2 第一天 2 1:计算机概述(了解) 2 (1)计算机 2 (2)计算机硬件 2 (3)计算机软件 2 (4)软件开发(理解) 2 (5) ...
- WOE:信用评分卡模型中的变量离散化方法(生存分析)
WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...
随机推荐
- 【VMware vCenter】使用cmsso-util命令进行链接、删除、修改多个vCenter Server(VCSA)的SSO域。
VMware vCenter Server 支持新安装的时候选择将vCenter SSO域加入到另外一个现有的SSO域中,同时也支持使用cmsso-util命令将现有的两个或多个vCenter SSO ...
- Mysql中的FOREIGN_KEY_CHECKS方法【外键约束作用】
一.命令行 首先FOREIGN_KEY_CHECKS方法的作用是用来启动和关闭外键约束的方法. 二.外键约束 即数据库中两个数据表之间的某个列建立的一种联系.MySQL通过外键约束的引入,可以使得数据 ...
- JSX 代码是如何“摇身一变”成为 DOM 的?
JSX 是一种语法,并不是 React 中的内容,时下接入 JSX 语法的框架越来越多,但与之缘分最深的仍然是 React.本节来讲一下 React 是如何摇身一变成为 DOM 的. 我们平时在写Re ...
- lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
-- create a class Animal={name = "no_name" , age=0 } function Animal:bark(voice) print(sel ...
- [CF403E]Two Rooted Trees
Two Rooted Trees 题面翻译 题目描述 你有两棵有根树,每棵树都有 \(n\) 个结点.不妨将这两棵树上的点都用 \(1\) 到 \(n\) 之间的整数编号.每棵树的根结点都是 \(1\ ...
- [UOJ#748] [UNR#6 1B] 机器人表演
在这个科技发达的年代,真人表演已经落伍了.参加完 UOI 后,hehe 蚤去到了下山市大剧院,观看下山市最火爆的机器人表演. 机器人有时比人类更能抓住事情的本质.所谓表演,其实也就是开场有若干个机器人 ...
- 数据库系列:业内主流MySQL数据中间件梳理
数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩容 数据库 ...
- Spring Boot 2.x 到 3.2 的全面升级指南
Spring Framework 是一种流行的开源企业级框架,用于创建在 Java Virtual Machine (JVM) 上运行的独立.生产级应用程序.而Spring Boot 是一个工具,可以 ...
- influxdb 进行数据删除和修改
本文为博主原创,转载请注明出处: 1.条件删除数据 InfluxDB 只支持基于时间的删除操作. 可以使用 DELETE 语句来删除指定时间范围内的数据.例如,以下的 SQL 语句将删除 measur ...
- java中的数据库连接池
常见的连接池的优缺点: HikariCP 优点: 性能出色,尤其在高并发负载下表现良好 内存消耗低,占用系统资源较少 具有自动化的连接池维护和统计功能 缺点: 需要 JDK7 或以上版本支持 配置选项 ...