离散化的思想和它的两种代码与区别

离散化的思想和它的两种代码与区别

2017年06月15日 12:44:41 AC之路有笑有泪 阅读数:6905

版权声明:觉得好的话就给他人分享一下吧,欢迎转载,码字不容易啊,转载麻烦注明出处 https://blog.csdn.net/xiangAccepted/article/details/73276826

离散化是什么:一些数字,他们的范围很大(0-1e9),但是个数不算多(1-1e5),并且这些数本身的数字大小不重要,重要的是这些数字之间的相对大小(比如说某个数字是这些数字中的第几小,而与这个数字本身大小没有关系,要的是相对大小)(6 8 9 4 离散化后即为 2 3 4 1)(要理解相对大小的意思)(6在这4个数字中排第二小,那么就把6离散化成2,与数字6本身没有关系, 8,9,4亦是如此)(2018.3.26 对这篇博客进行补充修改,被一道题的离散化卡到了,花了一晚上时间,才找到BUG(需离散化的数字有无相同的数字),黑体字为今晚对此篇博客进行了补充完善与区别)

离散化思想:因为数字太大,导致没有办法开那么大的数组,又因为数字个数并不多,这时候就可以对它们进行离散化,离散化是改变了数字的相对大小,例如,有500000个数字,他们的范围是0-1e9的,这样就满足离散化的条件。

就比如说,你可以开一个5e5的数组,但是你不能开一个1e9的数组。只改变这些数字的相对大小

第一种离散化

(包含重复元素,并且相同元素离散化后也要相同,推荐使用)
离散化以前一直搞不懂是怎么实现的,看了一个代码才明白。

  1. const int maxn=1e5+10;

  2.  

    int a[maxn], t[maxn], b[maxn];

  3.  

    int n;

  4.  

    scanf("%d",&n);

  5.  

    for(int i=1; i<=n; i++)

  6.  

    scanf("%d",a[i]),t[i]=a[i];

  7.  

    sort(t+1,t+n+1);

  8.  

    m=unique(t+1,t+1+n)-t-1;//求出的m为不重复的元素的个数

  9.  

    for(int i=1; i<=n; i++)

  10.  

    b[i]=lower_bound(t+1,t+1+m,a[i])-t;

  11.  

    //a[i]为原来的数组,b[i]为离散化后的数组

原来的a[i]离散化后成了后来的a[i];

离散化后的a[i]范围是(1-m);
举个栗子:
原序列:6 9 4 6 4
排序后:4 4 6 6 9
unique(元素去掉重复的)后:4 6 9 6 9  ( 感谢薇亚040214同学提出疑问,为什么unique去重后是4,6,9,6,9,而不是4,6,9,4,9,大家运行下面的代码即可,2018.7.21更)

SiriusNEO大佬的解答:unique去重完后面的元素是不变的,所以是4 6 9 6 9,具体可以看C++ Reference的源码
http://www.cplusplus.com/reference/algorithm/unique/?kw=unique   2018.8.6更)

  1. #include <cstdio>

  2.  

    #include <algorithm>

  3.  

    using namespace std;

  4.  

    int a[10]={6,9,4,6,4};

  5.  

    int main()

  6.  

    {

  7.  

    int n=5;

  8.  

    sort(a,a+n);//排序后4 4 6 6 9

  9.  

    n=unique(a,a+n)-a;

  10.  

    for(int i=0;i<5;i++)

  11.  

    printf("%d ",a[i]);

  12.  

    printf("\n");

  13.  

    //最后输出4 6 9 6 9

  14.  

    //SiriusNEO大佬的解答:unique去重完后面的元素是不变的,所以是4 6 9 6 9,具体可以看C++ Reference的源码

  15.  

    }

unique有一个返回值,例如有十个有序的数列3 3 5 5 6 6 6 7 7 8,不重复的数字有五个,使用unique去重之后数列变成了3 5 6 7 8 6 6 7 7 8,它只改变了前五个数字后边的不变,返回值是 最后一个改变的数字的地址。so:m=unique(t+1,t+1+n)-t-1;一般要减去首地址(t+1),m为不重复的数字的个数

原文地址:https://www.cnblogs.com/lxy050129/p/10084658.html

时间: 2024-10-11 14:29:51

离散化的思想和它的两种代码与区别的相关文章

UIImage两种初始化的区别

UIImage可以通过以下两种方式进行初始化: 1 //第一种初始化方式:[注意使用这种初始化的时候如果是png格式的可以不给后缀名,根据屏幕的的分辨率去匹配图片] 2 UIImage *image = [UIImage imageNamed:@"v_red_heart_selected"]; 1 //第二种初始化方式:[必须拼接图片的全名称,否则image的路径为空] 2 NSString *filePath = [[NSBundle mainBundle] pathForResou

PHP中数组合并的两种方法及区别介绍

PHP数组合并两种方法及区别 如果是关联数组,如下: 复制代码代码如下: $a = array( 'where' => 'uid=1', 'order' => 'uid', ); $b = array( 'where' => 'uid=2', 'order' => 'uid desc', ); 1. array_merge,如果两个数组存在相同的key,后面的一个会覆盖前面的 复制代码代码如下: <?php $c = array_merge($a, $b); var_expo

UIimage两种初始化的区别 广告轮播封装

UIimage两种初始化的区别 第一种初始化: UIImage *image = [UIImage imageNamed:@"xxx"];  注意(这种方法加载的图片如果后缀名是png的,可以不写后缀名,根据屏幕分辨率自己去匹配图片) 第二种初始化: NSString *path = [[NSBundle mainBundle] pathForResource:@"xxx.png" ofType:nil]; UIImage *image = [[UIImage al

jsp两种include指令区别

[转]:http://www.cnblogs.com/lazycoding/archive/2011/04/04/two_include.html <%@ include file="relativeURI"%> <jsp:include page="relativeURI" flush="true" /> 首先说明这两种都是什么: <%@ include file="relativeURI"%&

UIImage 两种初始化的区别

UIImage 两种初始化的区别 1.使用imageNamed:第一次读取的时候,先把这个图片放到缓存里,下次再使用到这个图片的时候直接从缓存中读取(优点:方便快捷,只有第一次使用的时候稍微慢,接下来在使用就会快点:缺点:如果在当前工程中只使用一次会浪费内存)[这个内次在程序关闭的时候才释放] 2.使用initWithContentsOfFile:每次都会根据路径去读取,不会占用内存,如果图片在当前工程中只使用一次,应该选用这个方法

创建后台任务的两种代码模式

创建后台任务的两种代码模式 后台任务是每个App都需要的一些行为,毕竟主线程是大爷,拖不起,伤不起,脏活累活都只能在不见天日的后台去做. 最简单的后台任务,可以说是直接开一个线程就可以了,或者说来个Service,再开个线程.但这些并不是官方认证的最佳实践,实际上,Google早就考虑到了这一点,并把这些需求进行了封装,给我们提供了非常好的后台任务解决方案,并在Training上进行了讲解: 官网镇楼: https://developer.android.com/training/best-ba

ACE_linux:Reactor与Proactor两种模式的区别

一.概念: Reactor与Proactor两种模式的区别.这里我们只关注read操作,因为write操作也是差不多的.下面是Reactor的做法: 某个事件处理器宣称它对某个socket上的读事件很感兴趣: 事件分离者等着这个事件的发生: 当事件发生了,事件分离器被唤醒,这负责通知先前那个事件处理器: 事件处理器收到消息,于是去那个socket上读数据了. 如果需要,它再次宣称对这个socket上的读事件感兴趣,一直重复上面的步骤: 下面再来看看真正意义的异步模式Proactor是如何做的:

Java中serialVersionUID的解释及两种生成方式的区别(转载)

转载自:http://blog.csdn.net/xuanxiaochuan/article/details/25052057 serialVersionUID作用:        序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.有两种生成方式:       一个是默认的1L,比如:private static final long serialVersionUID = 1L;       一个是根据类名.接口名.成员方法及属性等来生成一个64位的哈希字段,比如:    

IOS UIImage两种初始化的区别

UIImage可以通过以下两种方式进行初始化: 1 //第一种初始化方式:[注意使用这种初始化的时候如果是png格式的可以不给后缀名,根据屏幕的的分辨率去匹配图片] 2 3 UIImage *image = [UIImage imageNamed:@"v_red_heart_selected"]; 1 //第二种初始化方式:[必须拼接图片的全名称,否则image的路径为空] 2 NSString *filePath = [[NSBundle mainBundle] pathForRes