算法里面的离散化
一、离散化(discretization)在算法和数据结构中指的是将连续的输入数据映射到离散的值或者范围,从而使得处理和计算变得更高效。通常用于处理大范围或者无限可能的输入,以便将其转化为有限的、可以有效处理的范围。
离散化的定义
离散化的主要目的是将连续的值或大范围的值映射到一个有限的集合中,以便进行高效的存储和处理。这通常通过对连续的数据进行排序、分组、或者映射来实现。
离散化的步骤
- 排序和编号:对所有唯一的连续值进行排序,然后为这些值分配一个唯一的编号。
- 映射:使用一个映射函数,将原始数据的每个值转换为新的编号或索引。
应用场景
-
区间压缩:在处理大范围的整数值时,通过离散化可以将这些值映射到一个较小的范围。例如,处理1到10000的值时,可以将它们映射到1到100的范围内。
-
数据结构优化:在某些数据结构中(如树状数组或线段树),需要将离散化后的值作为索引来优化查询和更新操作。
离散化在以下方面有应用:
- 机器学习:将连续特征转换为离散类别,简化模型处理,例如将年龄分段成“青年”、“中年”、“老年”。
- 图像处理:将图像数据的连续像素值转换为离散的色彩级别,提高处理效率。
- 数据压缩:将连续信号如音频或视频离散化,以减少存储需求。
- 数据库设计:将连续数据映射到离散值,用于更高效的数据索引和查询。
这些应用帮助简化计算、提高效率或改善模型性能。
例子
例子 1:区间压缩
假设有一组连续的坐标值:[100, 150, 300, 600, 900]
。我们希望将这些值映射到更小的范围。
-
排序和编号:
- 排序后的值:
[100, 150, 300, 600, 900]
- 对这些值进行编号:
100 -> 1
,150 -> 2
,300 -> 3
,600 -> 4
,900 -> 5
- 排序后的值:
-
映射:
- 原始值
100
映射到编号1
- 原始值
150
映射到编号2
- 原始值
300
映射到编号3
- 原始值
600
映射到编号4
- 原始值
900
映射到编号5
这样,我们就将原始的连续值压缩到了
[1, 2, 3, 4, 5]
,这使得后续的数据结构(如线段树或树状数组)的操作更为高效。 - 原始值
例子 2:二维离散化
假设有一组二维坐标值:[(10, 20), (15, 30), (30, 60)]
。我们需要将这些坐标值离散化。
-
提取和排序:
- X轴坐标:
[10, 15, 30]
- Y轴坐标:
[20, 30, 60]
- 对X轴坐标编号:
10 -> 1
,15 -> 2
,30 -> 3
- 对Y轴坐标编号:
20 -> 1
,30 -> 2
,60 -> 3
- X轴坐标:
-
映射:
(10, 20)
映射到(1, 1)
(15, 30)
映射到(2, 2)
(30, 60)
映射到(3, 3)
这样,我们将原始的连续坐标转换成离散的坐标,对数据结构的处理(如二维树状数组)将更加高效。
总结
离散化的关键是将原始的、可能是连续或无限范围的数据,转化为有限且可处理的编号或索引。这样不仅优化了存储空间,也提高了数据处理的效率。
二、在算法中,“映射”是指将一个集合中的每个元素通过某种规则或函数转换为另一个集合中的元素的过程。这一概念广泛应用于数据处理、函数设计和数据结构中。以下是映射的详细解释:
1. 基本定义
映射可以被视为一个函数 ( f: A \rightarrow B ),其中 ( A ) 是定义域,( B ) 是值域。对于定义域中的每个元素 ( a \in A ),映射函数 ( f ) 将其转换为值域中的元素 ( b \in B )。形式上,这可以表示为 ( f(a) = b )。
2. 示例
-
数学中的映射:一个简单的数学映射是 ( f(x) = x^2 ),它将每个实数 ( x ) 映射到它的平方 ( x^2 )。
-
数据结构中的映射:在哈希表中,映射是通过哈希函数将键(key)映射到对应的值(value)。例如,键 "name" 可能映射到值 "Alice"。
3. 应用
-
数据转换:在数据处理过程中,可以将数据从一种格式转换为另一种格式。比如,映射函数可以将用户输入的字符串转换为对应的内部数据结构。
-
离散化:在离散化过程中,映射用于将连续的数据转换为离散的值。例如,将地理坐标映射到一个有限的网格系统中。
4. 复杂映射
映射不仅限于一对一关系,还可以是多对一(多个输入映射到一个输出)或一对多(一个输入映射到多个输出)。例如,在关系数据库中,某一用户ID可能映射到多个订单记录。
5. 映射的属性
- 单射(Injective):每个定义域的元素映射到值域中唯一的元素,不存在不同的输入映射到相同的输出。
- 满射(Surjective):定义域中的每个元素都映射到值域中的某个元素,使得值域中的每个元素至少被映射一次。
- 双射(Bijective):既是单射又是满射,即每个定义域的元素都有唯一的值域元素,且值域中的每个元素都有唯一的定义域元素。
映射在算法中扮演着重要角色,它使得数据转化、存储和处理变得更加系统化和高效。
了解了什么是离散化和映射,接下来直接开始做题,用题目实践才是最好的。
题目:区间和
假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。
现在,我们首先进行 n次操作,每次操作将某一位置 x上的数加 c。
接下来,进行 m次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。
输入格式
第一行包含两个整数 n和 m。
接下来 n 行,每行包含两个整数 x 和 c。
再接下来 m 行,每行包含两个整数 l 和 r。
输出格式
共 m 行,每行输出一个询问中所求的区间内数字和。
数据范围
≤x≤
,
1≤n,m≤,
≤l≤r≤
,
−10000≤c≤10000
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5
离散化的特点:
值域大,个数少。
可以把这n个数映射到它的下标。
常见的问题:
1. 数组a中有重复元素(去重)
2. 如何算出映射后的值?(二分)
此题把下标映射后前缀和求解即可。
#include<iostream>
#include<vector>
#include<algorithm>using namespace std;
typedef pair<int,int> PII;/*定义pair<int,int>类型为PII,就相当于取了一个别名,就是方便使用的时候不输入那么复杂又长的东西。*/
const int N=3e5+10;
/*因为有三个坐标,所以是用的3e5+10的范围。
输入的n个x,m个l,r,就是n+2m个坐标,因为n和m都是10的五次方,所以就是3乘10的5次方,多10是故意开的,害怕越界嘛。*/
int a[N],s[N];
/*这个就是求的区间和,只不过前面还有些步骤,所以这个a[N]数组是存储的值,不是坐标哈;s[N]
还是和前缀和一样,是放的前缀和的值。*/
vector<PII> add,query;
/*观察题目得到,输入的位置x和插入的值c,与后面输入的区间两个边界l,r一样,都是一次输入一对
的数进去,所以这里定义了一个PII类型的vector,来存储要操作的东西。这里面add是存储插入的位置x和值c,而query是查询区间,并求出指定区间的和,所以query存储的是边界l,r的位置*/
vector<int> alls;
/*alls是存储所有的位置的,不管是刚开始的x,还是l,r都存在里面,后面会操作的,很有用处。记住,vector是c++里面的可变数组,所以在进行和数组类似的操作时,也可以像数组那样使用,切记。*/int find(int x){int l=0,r=alls.size()-1;while(l<r){int mid=l+r>>1;//这里是整数,没有小数,所以可以用位运算。if(alls[mid]>=x) r=mid;//二分的第一个模板,相当于求最小值的那个,不用加1。else l=mid+1;}return r+1;//这里你写l+1也可以,反正最后二分l是约等于r的,都可以。/**注意返回的是r+1,就是最低是返回1,因为我要求前缀和,所以就这样。/
}
/*这个函数是利用的二分查找,来查找x在alls可变数组里面的位置,也就是x在alls可变数组的数组下标是多少。这其实就是离散化了,alls数组在之前的操作后,已经变得井然有序,每一个输入的坐标值x,l,r在alls里面都有对应的位置,这就已经将原来范围大,数目少且离散,不好处理的坐标给放在了alls数组里面,所以要注意,这个alls数组里面存的是坐标,如果要求对应的值的话,那么就是,例如:要想查询x位置上的值的话,那么就是:1、先找到x这个坐标在alls数组里面的哪个位置,对应的是alls数组的哪个下标。 2、找到了以后,就能迅速的在alls数组里面找到x坐标所在的位置。 3、找到位置后就直接能找到x所对应的值了。 这就是离散化:1、vector存输入的位置坐标;2、在这个vector里面找到需要的位置坐标。
3、找到以后就可以像之前那样正常操作了,想查值就查值,想求前缀和就求前缀和。*/int main(){int n,m;cin>>n>>m;for(int i=0;i<n;i++){int x,c; cin>>x>>c;add.push_back({x,c});alls.push_back(x);}
/*输入n,m,并且输入x,c,这x,c是插入所需要的值,所以将这两个值存到add这个vector里面。然后顺便把位置x存入alls这个可变数组里面。*/for(int i=0;i<m;i++){int l,r;cin>>l>>r;query.push_back({l,r});alls.push_back(l);alls.push_back(r);}
/*输入l,r,并将后面查询求前缀和所需要的值l,r给存入到query这个vector里面去,同时,l,r这两个表示位置的数,也全部存到alls这个可变数组内。*/ sort(alls.begin(),alls.end());//排序alls里面的所有坐标值alls.erase(unique(alls.begin(),alls.end()),alls.end());//去重并调整里面的坐标值。
/*所有输入的关于位置的数,也就是所谓的坐标,已经排序去重并调整大小了,经过了这两步,得到的是
有序的,且中间没有空位的,新的alls可变数组,这对于后面的离散化是很重要的。*/ for(auto item:add){int x=find(item.first);//找x这个坐标在alls数组里面的数组下标是多少。a[x]+=item.second;//在alls数组里面找到x所在的位置后,就直接执行c的插入操作就可以了。}//插入操作for(int i=1;i<=alls.size();i++) s[i]=s[i-1]+a[i];//注意i<=alls.size(),是从下标1开始的,不是0.
/*这里还是和求前缀和是一样的,在求前缀和之前都要定义一下前缀和的表示,在我看来就是定义一种性质嘛,注意这里是i从1开始,不从0开始是为了避免边界问题。*/for(auto item:query){//这个不一定要写成item,随便写自己喜欢的单词就好,不影响的。int l=find(item.first),r=find(item.second);//分别求l,r在alls数组里面的位置。printf("%d\n",s[r]-s[l-1]);//这就是求前缀和,直接用公式就可以,这是一维前缀和哦。}//查询并求前缀和的操作/*这里面的first,second就是键值,因为我的add和query的vector都是PII类型的,也就是pair<int,int>类型的,就拿这里来说,这里query的item.first指的是输入的l,而item.second指的是输入的r。*/return 0;
}
上面是y总的分析,我觉得分析的挺好的。
以上就是我对于算法里面的离散化的看法与理解,就这样吧。
相关文章:

算法里面的离散化
一、离散化(discretization)在算法和数据结构中指的是将连续的输入数据映射到离散的值或者范围,从而使得处理和计算变得更高效。通常用于处理大范围或者无限可能的输入,以便将其转化为有限的、可以有效处理的范围。 离散化的定义…...

Https AK--(ssl 安全感满满)
免责声明:本文仅做分享! 目录 https探测 openssl Openssl连接服务器获取基本信息 连接命令: 指定算法连接: 测试弱协议连接是否可以连接: 得到的内容包括: sslscan 在线查询证书 https AK type 中间人AK sslsplit 工具…...

ERROR: Failed building wheel for cython_bbox | pip install cython_bbox 失败【解决方案】
🥇 版权: 本文由【墨理学AI】原创首发、各位读者大大、敬请查阅、感谢三连 🎉 声明: 作为全网 AI 领域 干货最多的博主之一,❤️ 不负光阴不负卿 ❤️ 文章目录 win11 系统 pip3 install cython_bbox 失败报错如下解决方法:1 下载…...
逻辑与位运算的双面舞者:、、|、||深度解析
深入解析&、&&、|、||:逻辑与位运算的奥秘之旅 在编程的世界里,&、&&、|、||这四种运算符扮演着至关重要的角色。它们不仅仅是简单的符号,更是连接程序逻辑、实现复杂功能的桥梁。本文旨在深入探讨这四者的区别与联…...

中断门+陷阱门
中断门: 中断描述符在IDT表里面 kd> dq idtr 80b95400 83e48e000008bfc0 83e48e000008c150 80b95410 0000850000580000 83e4ee000008c5c0 80b95420 83e4ee000008c748 83e48e000008c8a8 80b95430 83e48e000008ca1c 83e48e000008d018 80b95440 000085000050…...

RTMP直播播放器的几种选择
如何选择RTMP播放器? 在选择RTMP播放器时,需要综合考虑多个因素,以确保选择的播放器能够满足实际需求并提供良好的用户体验。以下是一些选择RTMP播放器的建议: 1. 功能需求 低延迟:对于直播场景,低延迟是…...

初识爬虫1
学习路线:爬虫基础知识-requests模块-数据提取-selenium-反爬与反反爬-MongoDB数据库-scrapy-appium。 对应视频链接(百度网盘):正在整理中 爬虫基础知识: 1.爬虫的概念 总结:模拟浏览器,发送请求,获取…...

【趣学Python算法100例】兔子产子
问题描述 有一对兔子,从出生后的第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子,假设所有的兔子都不死,问30个月内每个月的兔子总对数为多少? 题目解析 兔子产子问题是一个有趣的古典数学问题,…...
HTTP 四、HttpClient的使用
一、简单介绍 1、简介 HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。HttpClient已经应用在很多的项目中,比如Apache Jakarta上很著…...
C语言:结构体变量
1. 结构体变量的引用方法 例如,若有数据定义: struct Student{char name[10];int age;struct Date birthday; }s1,s2,stu[10]; 则下面对结构体变量的引用都是正确的: s1.age20; scanf("%d",&s1.age); gets(stu[0].name); s…...
bibtex是什么
BibTeX 是一个用于处理和格式化参考文献的工具,常与 LaTeX 一起使用。它提供了一种方便的方式来管理和生成参考文献列表,特别适用于学术写作和科研论文中。以下是对 BibTeX 的详细介绍: 基本概念 BibTeX 是 LaTeX 的一个附加工具࿰…...

【大模型专栏—进阶篇】智能对话全总结
大模型专栏介绍 😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本文为大模型专栏子篇,大模型专栏将持续更新,主要讲解大模型从入门到实战打怪升级。如有兴趣,欢迎您的阅读。 Ǵ…...
MVC应用单元测试以及请求参数的验证
SpringMVC支持对Controller单元测试 RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(locations {"classpath:mvc-dispatcher-servlet.xml", }) WebAppConfiguration public class ControllerJUnitBase{Resourceprivate RequestMappingHandlerMappin…...

算法:TopK问题
题目 有10亿个数字,需要找出其中的前k大个数字。 为了方便讲解,这里令k为5。 思路分析(以找前k大个数字为例) 很容易想到,进行排序,然后取前k个数字即可。 但是,难点在于,10亿个数…...
.json文件的C#解析,基于Newtonsoft.Json插件
目录 1. 前言 2. 正文 2.1 问题 2.2 解决办法 2.2.1 思路 2.2.2 代码实现 2.2.3 测试结果 3. 备注 1. 前言 天气晚来秋,这几天天气变凉了,各位同学注意好多穿衣服。回归正题 由于需要,需要将json的配置里面的调理解析出来,做成接口,以便于开发。 2. 正文 2.1 …...

四、(JS)JS中常见的加载事件
一、文档加载监听 (1)抛出疑惑,什么是文档加载监听?为什么要有这个东西? 老样子,我们先讲一个场景,带着大家熟悉为什么会有文档加载监听,是来解决什么问题来着的。 我们先看下这段…...

[网络]https的概念及加密过程
文章目录 一. HTTPS二. https加密过程 一. HTTPS https本质上就是http的基础上增加了一个加密层, 抛开加密之后, 剩下的就是个http是一样的 s > SSL HTTPS HTTP SSL 这个过程, 涉及到密码学的几个核心概念 明文 要传输的真正意思是啥 2)密文 加密之后得到的数据 这个密文…...
React 嵌套类名样式不生效
修改前 父级.blog样式生效,子级.circle样式不生效 // app/blog/page.js import styles from "./page.module.scss"export default function Blog () {return (<div className{styles.blog}><div classNamecircle><div /></div>…...

20Kg载重30分钟续航多旋翼无人机技术详解
一、机架与结构设计 1. 材料选择:为了确保无人机能够承载20Kg的负载,同时实现30分钟的续航,其机架材料需选用轻质高强度的材料,如碳纤维或铝合金。这些材料不仅具有良好的承重能力,还能有效减轻无人机的整体重量&…...
详解c++:认识类
文章目录 前言一、类是什么二、类(class)的使用publicprivate:protected: 前言 C 是一种面向对象的编程语言。面向对象编程是一种编程范式,它使用“对象”来设计软件应用程序。在面向对象编程中,对象包含了…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...