离散化

离散化是数据预处理的重要步骤,本文详细介绍了如何使用C++中的sort(), unique(), lower_bound()和vector::erase()实现离散化。首先对数据排序,然后通过unique()去除重复元素,接着使用erase()删除多余的重复项。最后,利用lower_bound()找到原始数据在排序后数组中的位置,从而完成离散化过程。此外,还讨论了二维数组的离散化实现,强调了二维数组与一维数组之间的转化关系。" 115097890,10547526,PHP-FPM实时负载监控详解,"['PHP', '后端开发', '服务器监控', 'Web开发', 'Nginx配置']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 什么是离散化?
2 离散化的实现
用到了泛型算法中的sort(),unique(),lower_bound()和vector中的erase()
erase() 删除vector中的指定元素
unique() "去掉"容器中相邻元素的重复元素,这里的“去掉”是伪去除,会把重复的元素添加到容器末尾,返回的是去重之后的尾地址。一般使用前需要对容器进行排序
lower_bound() 返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于等于value 的值。lower_bound() 使用前必须保证序列是有序的。
具体步骤如下:
记要离散化的一维数组为int initial[N]
声明一个vector 的数组 a,将initial的值全部压入a中。举例:a中的元素分别为 1,3,2,1,6,7,3,2,5
①先对a进行排序 sort(a.begin(),a.end()); 经过排序后a中的元素变为:1,1,2,2,3,3,5,6,7
②对a使用unique()函数:将a中的重复元素添加到a的末尾,返回的是去重后的尾地址。 经过unique()之后的a变为:1,2,3,5,6,7+重复元素,此时返回值指向元素7
③对a使用erase函数:擦掉区间【unique的返回值,a.end())的重复元素,即a.erase(find(a.begin(),a.end()),a.end()); 经过erase之后a变为:1,2,3,5,6,7。此时,a中就不重复地有序地列举了所有出现过的元素。
④找到initial中每个元素在a中的位置(通过lower_bound()获取)即为它们离散化后的数值(习惯上,离散化后的数值从1开始),即initial[i]=lower_bound(a.begin(),a.end(),initial[i])-a.begin()+1。加1是因为离散化后的数值习惯从1开始,如果不加1就是从0开始。
离散化模板:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


//地址传递
void discretization(int * initial, int len)
{
	vector <int> a;
	a.insert(a.begin(), initial, initial + len);

	cout << "initial:";
	vector <int> ::iterator it = a.begin();
	for (; it != a.end(); it++)
		cout << *it << "   ";
	cout << endl;
	//sort
	sort(a.begin(), a.end());

	//core code
	a.erase(unique(a.begin(), a.end()), a.end());

	//lower_bound()
	cout << "after discretization:";
	for (int i = 0; i < len; i++)
	{
		initial[i] = lower_bound(a.begin(), a.end(), initial[i]) - a.begin() + 1;
	}
}
void main()
{
	int blen = 9;
	int b[9] = { 1,3,2,1,6,7,3,2,5 };
	discretization(b, blen);
	for (int i = 0; i < blen; i++)
	{
		cout << b[i] << "  ";
	}
	cout << endl;
}

3 二维数组离散化的实现
基本思路:
①先把二维数组的值一一映射到一个一维数组中,二维数组的行列分别为n,m,则一维数组的长度为n*m
②然后传入参数,调用离散化函数
③得到的返回值是一维数组,再反映射回二维数组。
离散化函数没变,主要是主函数中添加了调用前二维数组转一维数组,调用后一维数组转回二维数组。
具体代码:

void main()
{
	int bn = 3;
	int bm = 3;
	int b[3][3] = { {1,3,2},{1,2,1},{1,100,2} };
	int size = bn * bm;
	int *c = new int[size];
	for (int i = 0; i < bn; i++)
	{
		for (int j = 0; j < bm; j++)
			c[i*bm + j] = b[i][j];
	}
	discretization(c, size);
    
	cout << "after discretization:"<<endl;
	for (int i = 0; i < bn; i++)
	{
		for (int j = 0; j < bm; j++)
		{
			b[i][j] = c[i*bm + j];
			cout << b[i][j]<<"  ";
		}
	  cout << endl;
	}
	
};

收获:一维数组和二维数组在本质上是一样的,二维数组逻辑上是二维的,但实际在内存中它是一维数组。二维数组和一维数组可以相互转化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值