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;
}
};
收获:一维数组和二维数组在本质上是一样的,二维数组逻辑上是二维的,但实际在内存中它是一维数组。二维数组和一维数组可以相互转化。