美文网首页C++半月刊
【C++半月刊#1】C++实用技巧——离散化

【C++半月刊#1】C++实用技巧——离散化

作者: 小垚说球 | 来源:发表于2019-02-09 21:43 被阅读0次
离散化是程序设计中一个常用的技巧,它可以有效的降低时间和空间复杂度。

离散化,就是把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。
打个比方:现在有一组很大的数据

1,23424,21472313246768,6594,95,0,65535313

如果将这些数作为数组的下标来保存对应的属性时,我们将需要开一个很大的数组。以上方数据为例,这个数组至少要开21472313246768这么大的空间,这样很多题目的空间限制这关都过不了了,怎么办呢?当数据只需表示出它们之间的相对大小关系,而不需表示出具体数值时,我们就要用一个小技巧——离散化。
还是以上面的数据为例,经过离散化处理后,数据就成了:

1,4,6,3,2,0,5

神不神奇,意不意外!!!

——不意外!!!

在这里,我就献上处理数据的程序,教大家如何实现。
第一种方法:

const int N=1e5+7;
int t[N],a[N];
int main()
{
  cin>>n;
  for(int i=1;i<=n;i++)
    cin>>a[i],t[i]=a[i];
  sort(t+1,t+n+1);
  m=unique(t+1,t+n+1)-t-1;
  for(int i=1;i<=n;i++)
    a[i]=lower_bound(t+1,t+m+1,a[i])-t;
}

在这段代码中,a[]经过离散,范围就变成了m。解释一下,unique是c++自带的一个函数,表示对一个数列去重,然后返回不重复的元素个数,当然在后面要减去首地址。那么这种离散化对于有重复元素的数列也可以适用,但复杂度相对后面要讲的第二种方法会高些。
比如,这组数据:

1,23424,242,65466,242,0

进入这段代码后,首先会排个序得到:

0,1,242,242,23424,65466

然后会去重,得到:

0,1,242,23424,65466

然后离散化的到:

1,3,2,4,2,0

第二种方法:

const int N=1e5+7;
struct Node
{
  int v,id;
  bool operator < (const Node a)const
  {return v<a.v;}
}a[N];
int n,rank[N];
int main()
{
  cin>>n;
  for(int i=1;i<=n;i++)
  {
    cin>>a[i].v;
    a[i].id=i;
  }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
      rank[a[i].id]=i;
 }

这种方法复杂度比上面那一种要优,但不能处理重复元素。它直接用结构体存储原本的数列的元素的位置,然后排序以后将他们再重新赋值。那么rank[]就是结构体a[]离散化后的结果。

v: 3 6 5 10 8
id : 1 2 3 4 5

排序以后:

v: 3 5 6 8 10
id: 1 3 2 5 4

所以离散化以后:

v: 3 5 6 8 10
id: 1 3 2 5 4
rk: 1 2 3 4 5

在按原来的顺序排列:

v: 3 6 5 10 8
rk: 1 3 2 5 4

今天的讲解就到了这里,相信大家对离散化有一定的了解了。来,做个题目练练手吧:
P1056图形面积-vijos
P1667 数列-洛谷

来自简书
发表于:2019-2-9
已同步至:
  • 简书
  • 头条号(今日头条)
  • 新浪微博

参考文献:
离散化_百度百科
离散化 - HolseLee - 博客园

C Studio工作室出品

作者微博

相关文章

  • 【C++半月刊#1】C++实用技巧——离散化

    离散化是程序设计中一个常用的技巧,它可以有效的降低时间和空间复杂度。 离散化,就是把无限空间中有限的个体映射到有限...

  • C++查内存泄漏

    转自轮子C++实用技巧(一) 1 #define _CRTDBG_MAP_ALLOC 2 #include ...

  • C++知识50问

    C++知识50问1、C和C++的区别?C++相对于C的优势。答:C是C++的基础,C++是C的超集。C是一个结构化...

  • 极客班第一周学习笔记

    初识C++ C++是在C之上基于对象,面向对象的编程语言。c++相比c在编程上更加模块化,具象化。 C++代码规范...

  • C++变量声明与定义

    一、变量的初始化方式 1、C、C++通用初始化方法 1、常用的初始化语法,沿用于C语言 2、C++特有的变量初始化...

  • c++ python java

    c++ 初始化 C++类中成员变量的初始化有两种方式 - yu132563的专栏 - CSDN博客 C++ 变量初...

  • c++学习笔记——第一天

    一、c++综述 (1)书籍推荐 ①、c++ primer ②、c++ primer plus ③、c++编程思想 ...

  • 高斯滤波

    二维高斯函数 高斯模板 高斯函数离散化并归一化。得到的是浮点值。下面是一个3X3的例子 C++代码

  • python3 c++ 和 java

    基本语法 长度 python c++ java 标准化输入&输出 python c++在C++中,标准的输入输出是...

  • 2019-07-13(day040_灰度化 二值化时,阈值t的选

    c++ c++中的新知识点:灰度化二值化时,阈值t的选取二值化

网友评论

    本文标题:【C++半月刊#1】C++实用技巧——离散化

    本文链接:https://www.haomeiwen.com/subject/mdmosqtx.html