离散化

离散化是一种数据处理的技巧,本质上可以看成是一种 哈希,其保证数据在哈希以后仍然保持原来的全/偏序关系。
https://oi-wiki.org/misc/discrete/
通俗地讲就是当有些数据因为本身很大或者类型不支持,自身无法作为数组的下标来方便地处理,而影响最终结果的只有元素之间的相对大小关系时,我们可以将原来的数据按照排名来处理问题,即离散化。

用来离散化的可以是大整数、浮点数、字符串等等。
最常见方法:排序+去重+二分

//数据离散化_排序+去重 void discrete() { sort(lan.begin(), lan.end()); //排序 lan.erase(unique(lan.begin(), lan.end()), lan.end()); //去重 } //查询 int query(int x) { return lower_bound(lan.begin(), lan.end(), x)-lan.begin(); //返回所查询的数据的下标 }

函数封装

//函数接受需要离散化的vector和离散化后对应的数从start开始两个参数 //返回的是离散化的结果vector,下标与原来的下标一样,存的值是我们想要的,也是find函数下想要的。 //odata[i]离散化的结果是res[i] vector<int> discrete(const vector<int>& odata, int start = 0) { // const int n = odata.size(); auto copy = odata;//对原数组的拷贝操作 sort(copy.begin(), copy.end()); // 考虑重复值 copy.erase(unique(copy.begin(), copy.end()), copy.end()); vector<int> res(n); for (int i = 0; i < n; i += 1) { // lower_bound >= 由于数值本身就存在,因此必然是找到=的情况 res[i] = lower_bound(copy.begin(), copy.end(), odata[i]) - copy.begin() + start; } return res; }

2.借助 map 自动排序

vector<int> discrete(const vector<int>& odata, int start = 0) { const int n = odata.size(); // C++中的map自带升序效果 // <数值,下标> map<int, int> autoSort; for (int i = 0; i < n; i += 1) { autoSort[odata[i]] = i; } //autosort排序后,小数在前面, vector<int> res(n); for (auto it = autoSort.begin(); it != autoSort.end(); ++it) { res[it->second] = start; start += 1; } return res; } 999在原来的数中排名第15小,它会被映射成15,我们需要保证结果和999这个值没有关系,或者只和相对大小的有关。代入题目例子更容易理解,可以看acwing板子题区间和https://www.acwing.com/problem/content/804/

不需要保序的离散化,可以在线做

//哈希表实现

unordered_map<int, int> S; int n=0; int get(int x) { if (S.count(x) == 0) S[x] = ++ n; return S[x]; }

__EOF__

本文作者爱飞鱼
本文链接https://www.cnblogs.com/mathiter/p/17827755.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   potential-star  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示