离散化的初阶应用

1.离散化的概念

      给出一列数字,在有些情况下,我们只需要知道这些数的相对大小,而不关心这些数字的绝对大小,比如,对一个班级的学生成绩进行排名,我们最终只要排名就可以,不需要关心其成绩的绝对值。

“离散化”就是用数字的相对值代替它们的绝对值。离散化是一种数据处理技巧,它把分布广泛的数据转换为密集分布,从而能够让算法更快,更省空间地处理。

离散化的步骤如下:

1.排序,首先对数组元素排序,这样我们才能确定相对大小。

2.离散化,把排序后的元素从1开始逐个分配数值,完成离散化。

3.归位,把离散化的每个元素放回到原始位置,结束。

离散化的编码比较简单,可以自己编码或者借用STL中的函数。

这里先简单说一些STL中的函数:它们分别是lower_bound()(实现离散化)和unique()(去除重复元素),lower_bound函数的功能是在有序的数列中查找某个元素的相对位置,这个位置正好是做离散化时元素初值对应的新值。但是遗憾的是这类函数只适用于一维数组的离散化,也就是说,类似于结构体,二维坐标之类的数据就不行了,这里我们以自己编码实现离散化为主,在后面的进阶中我会继续深入分析离散化的应用。

2.离散化的手工编码

我们还是以例题的形式来展现其实现方式,方便理解和掌握:

2.1 人物风云榜

 

#include <bits/stdc++.h>
#define maxn 100005
using namespace std;

struct node {
	int id, val;//id为元素的位置,val为元素的值
}olda[maxn];
int newa[maxn];
int n;
bool cmp(node a, node b)
{
	return a.val > b.val;
}

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &olda[i].val);
		olda[i].id = i;
	}
	sort(olda + 1, olda + n + 1, cmp);
	for (int i = 1; i <= n; i++)
	{
      newa[olda[i].id] = i;//这个元素的位置原来在olda[i].id,把它赋值为i,i是离散化后的新值
		if (olda[i].val == olda[i - 1].val)
			newa[olda[i].id] = newa[olda[i - 1].id];//若两个元素原值相同,则把新值赋值为相同
	}
	for (int i = 1; i <= n; i++)
		printf("%d ", newa[i]);
	printf("\n");
	return 0;
}

2.2点的离散化

 这个题的特点是不用去重,少了一个步骤,

#include <bits/stdc++.h>
#define maxn 1000005
using namespace std;

struct node {
	int id, x,y;
}olda[maxn];
int newa[maxn];
int n;
bool cmp(node a, node b)
{
	if (a.x == b.x)
		return a.y < b.y;
	return a.x < b.x;
}

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		scanf("%d%d", &olda[i].x,&olda[i].y);
		olda[i].id = i;
	}
	sort(olda + 1, olda + n + 1, cmp);
	for (int i = 1; i <= n; i++)
	{
		printf("%d %d\n", olda[i].x, olda[i].y);
		newa[olda[i].id] = i;
	}
	for (int i = 1; i <= n; i++)
		printf("%d ", newa[i]);
	printf("\n");
	return 0;
}

相信这两道题能让你初步了解离散化了,离散化是一个基本技巧,应用很多,这里先不展开讲解了,后续也会加急跟进后续的进阶学习,你的点赞是对up最大的支持......(咳咳,串台了~~~)其实只要是能一个人的文章里学到东西,写这些东西就有意义,我更喜欢凭本事拿到点赞的博主,作为菜狗的我自然还有很长的路要走,初阶的认知概念,还希望大佬勿喷~~~

3.金句省身

      接受自己的普通,然后拼尽全力去与众不同,不想输不需要理由,山茶花遇见贵人也会开放,滴水的日积月累也会穿石,只要自己不怕输,不认输,就不是理由。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值