C语言离散化

最近看到STL就不想用, 于是写个C语言离散化, 居然能过主席树板子, 就写个博客介绍一下.

qsortbsearch都在<stdlib.h><cstdlib>里.

什么是离散化

一种映射, 可以把值域从 \([1, Val_{\max}]\) 变成 \([1, N]\) 且保留大小关系, 多用于值域线段树和各种需要从值域考虑的数据结构.

如何离散化

1. 排序

可以用C语言的排序函数void qsort(void *bg, int len, int sz, int *cmp(const void *, const void *)).

先讲一下qsort.

  • bg为开始地址, 比如数组 \(a\) 从 \(1\) 开始就是 \(a + 1\) .
  • len为数组长度, 一般用 \(N\) .
  • sz为元素大小, 直接sizeof(type)简单粗暴, 如sizeof(long long).
  • cmp为比较函数, 传入两个void*类型的地址需要转换成原类型, 以下称第一个参数强转后访问到的值为\(x\)第二个为 \(y\), \(x < y\) 时返回负数, \(x = y\) 返回 \(0\), \(x > y\) 时返回正数, 比如排序字符串可以直接用strcmp, 排序整数则可以直接返回 \(x - y\).

那么很显然, 排序的代码就写出来了.

int cmp(const void *x, const void *y) // 比较
{return *(int*)(x) - *(int*)(y);} void lsh() { // 离散化
// b 是离散化用的辅助数组, 已经在输入时就是 a 的复制了
// S 是输入的长度
qsort(b + 1, S, sizeof(int), cmp);
/*
有一种逆天的写法, 感兴趣的同学可以探索一下匿名函数, 仅限C++11以上
qsort(b + 1, S, sizeof(int), [](const void *x, const void *y){return *(int*)(x) - *(int*)(y);});
*/
// 待续写
}

2. 降重

这里我们使用在原数组直接降重, 类似

if (a[i] ^ a[i - 1]) // 如果 a[i] 不等于 a[i - 1]
stk[++tp] = a[i] // 在栈顶加入 a[i]

所以很容易写出去重代码.

int cmp(const void *x, const void *y)
{return *(int*)(x) - *(int*)(y);} void lsh() {
qsort(b + 1, S, sizeof(int), cmp);
N = 1; // N 是离散化后的值域大小
lim (i, 2, S, 1) // for (int i(2); i <= S; i += 1)
if (b[i] ^ b[i - 1]) // 如果这个元素没有重复
b[++N] = b[i]; // 放在上一个不重复的后面
// 待续写
}

二分查找在离散化后的值域中的大小

二分查找可以用C语言的void* bsearch(void *val, void *bg, int len, int sz, int cmp(const void *, const void *)).

bsearchqsort基本一样, 这里只讲一下不一样的地方.

  • val是要找的值的地址.
  • 返回的是void*类型的地址, 需要强转再使用.

那么也可以写出最后完成的代码.

int cmp(const void *x, const void *y)
{return *(int*)(x) - *(int*)(y);} void lsh() {
qsort(b + 1, S, sizeof(int), cmp);
N = 1;
lim (i, 2, S, 1)
if (b[i] ^ b[i - 1])
b[++N] = b[i];
lim (i, 1, S, 1) // 原数组 a 的每个元素的离散化值都要找
// 二分查找后强转然后减去头地址 (b + 1) 后加 1 避免 0
// 稍微优化一下 - (b + 1) + 1 就是 - b
a[i] = (int*)bsearch(a + i, b + 1, N, sizeof(int), cmp) - b;
}

C语言离散化的更多相关文章

  1. CF670C cinema

    想必是个半水题,div2的C嘛 仔细观察,发现排序可做. 怎么排序呢?排啥呢?拿啥离散化,拿啥结构体呢? 仔细思考热静分析,便可得出结论: 以每个人会的语言离散化,把每个电影建结构体后不排序,而是枚举 ...

  2. R语言︱噪声数据处理、数据分组——分箱法(离散化、等级化)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 分箱法在实际案例操作过程中较为常见,能够将一些 ...

  3. PID控制算法的C语言实现二 PID算法的离散化

    上一节中,我论述了PID算法的基本形式,并对其控制过程的实现有了一个简要的说明,通过上一节的总结,基本已经可以明白PID控制的过程.这一节中先继续上一节内容补充说明一下. 1.说明一下反馈控制的原理, ...

  4. 增量式PID推导及C语言实现

    PID控制器表达式为: \[ u(t) = K_pe(t) + K_i\int_0^t e(\tau)d\tau + K_d\frac{de(t)}{dt} \] 离散化: 令 $ t = nT,~T ...

  5. R语言进行机器学习方法及实例(一)

    版权声明:本文为博主原创文章,转载请注明出处   机器学习的研究领域是发明计算机算法,把数据转变为智能行为.机器学习和数据挖掘的区别可能是机器学习侧重于执行一个已知的任务,而数据发掘是在大数据中寻找有 ...

  6. R语言︱贝叶斯网络语言实现及与朴素贝叶斯区别(笔记)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 一.贝叶斯网络与朴素贝叶斯的区别 朴素贝叶斯的 ...

  7. R语言︱异常值检验、离群点分析、异常值处理

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:异常值处理一般分为以下几个步骤:异常 ...

  8. R语言︱函数使用技巧(循环、if族/for、switch、repeat、ifelse、stopifnot)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 后续加更内容: 应用一:if族有哪些成员呢?- ...

  9. 牛客练习赛38 D 题 出题人的手环 (离散化+树状数组求逆序对+前缀和)

    链接:https://ac.nowcoder.com/acm/contest/358/D来源:牛客网 出题人的手环 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  10. R语言︱处理缺失数据&&异常值检验、离群点分析、异常值处理

    在数据挖掘的过程中,数据预处理占到了整个过程的60% 脏数据:指一般不符合要求,以及不能直接进行相应分析的数据 脏数据包括:缺失值.异常值.不一致的值.重复数据及含有特殊符号(如#.¥.*)的数据 数 ...

随机推荐

  1. windows在cygwin64下使用acme.sh批量签发Let's Encrypt的ssl证书,并用powershell重新分配iis证书

    使用前提 本脚本是在使用阿里云Windows服务器的前提,如果使用其他dns服务,请参看acme.sh的dns相关文档 配置好cygwin64.acme.sh并配置好阿里云账户,openssl最好也安 ...

  2. JAVAEE——maven安装

    一.安装本地Maven 注意:检查JAVA_HOME环境变量, maven本身就是java写的,所以要求必须先安装JDK,检查本机jak环境win+r后输入cmd,然后输入java -version, ...

  3. AD域下,域管理员网络无法正常连接

    排错思路:1.是否拥有上网权限, test 超级管理员自然是有上网权限的(该项排除): 2.浏览器是否使用了代理 ,有些软件在安装的时候,会自动启用浏览器的代理,开启某些特定的端口: 3.其他原因 解 ...

  4. Shell分析服务器日志命令

    1.查看有多少个IP访问: awk '{print $1}' log_file|sort|uniq|wc -l 2.查看某一个页面被访问的次数: grep "/index.php" ...

  5. LeetCode 1316. Distinct Echo Substrings (RK哈希)

    题意: 给一个字符串 寻找字符串为(a+a)格式的子串有多少.a+a 格式字符串比如 abcabc, ee 等. 首先O(N^2)枚举子串,然后通过哈希在O(1)复杂度判断子串是否符合要求. RK哈希 ...

  6. 1.1 HELLO 窗口

    跟着教程,开始第一步创建窗口吧!这一节不涉及太多知识. 本节会出现一些名词,我们现在只需要知道它们大概是干什么的就行. ● GLFW:一个专门针对OpenGL的C语言库,通过它提供的接口,我们就可以渲 ...

  7. MobileNet V2中InvertedResidual实现

    1.为了方便理解其本身结构,找到源码理解一下. 2.论文地址:http://arxiv.org/pdf/1801.04381.pdf 3.V2相比较V1增加了倒残差结构和线性瓶颈层.整个结构按照维度来 ...

  8. iOS关于NSNotificationCenter通知使用小结

    常用的页面之间传值方式是参数,单例,通知,委托,以及其他全局变量等等.通知是一种广播形式,可以一对多通知传值.最近在项目中用的模块化开发, 通过封装抽取,将页面分为上中下三个模块.最简单的方式是把所有 ...

  9. java截取##间的话题字符串

    转载MARK一下,百度根据关键字不好搜到,省的下次到处找.package iqiyi.com.model;import java.util.regex.Matcher;import java.util ...

  10. KubeSphere 在直播应用中的实践

    本文是上海站 Meetup 讲师唐明根据其分享内容整理的文章. 引言 目前媒体的主流传播渠道已从传统的报纸.广播.电视转向了互联网,各种视频及社交 App 成为了人们获取资讯的首选途径.苏州市广播电视 ...