离散化算法

离散化

在C++中,离散化通常指的是将连续的数值或数据转化为离散的形式。这在数值分析、信号处理、图像处理和机器学习等领域都非常常见。以下是一些离散化的基本概念和方法:

1.区间划分:

将连续变量的值域分成多个区间,每个区间对应一个离散的值。例如,将浮点数分成若干个区间,可以用区间的中点、边界或其他代表值来替代该区间内的所有值。

2.量化:

在信号处理中,量化是将连续信号转换为离散信号的过程。可以使用固定点数表示或浮点数表示。

3.

插值与样本选择:在离散化过程中,可以通过插值技术生成离散样本,或选择数据集中的特定样本点。

前缀和算法
二分查找

我们来看一道题可以帮助我们更好的理解这个算法


Acwing804.区间和

我们举个例子:

我们现在根据题来看,题中是进行了3次读操作3次写操作。

代码如下:

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

const int N = 300010;
int n, m;        // n 表示插入操作的数量,m 表示查询操作的数量
int a[N];        // 用于存储每个离散化后位置的值
int s[N];        // 前缀和数组
vector<int> alls; // 用于存储所有需要离散化的坐标
vector<pair<int, int>> add, query; // 分别存储插入操作和查询操作

// 二分查找,找到 x 在 alls 中对应的位置(离散化)
int find(int x)
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x)  // 如果中间值大于等于 x,右边界缩小
            r = mid;
        else                 // 否则左边界增大
            l = mid + 1;
    }
    return r + 1;  // 返回离散化后的索引(从 1 开始)
}

int main()
{
    // 读取插入操作和查询操作
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        int x, c;
        cin >> x >> c;
        alls.push_back(x);          // 收集需要离散化的 x 坐标
        add.push_back({x, c});      // 保存插入操作
    }  
    for (int i = 1; i <= m; i++)
    {
        int l, r;
        cin >> l >> r;
        alls.push_back(l);          // 收集查询范围的左端点
        alls.push_back(r);          // 收集查询范围的右端点
        query.push_back({l, r});    // 保存查询操作
    }
    // 去重并排序,完成离散化准备
    sort(alls.begin(), alls.end());                          // 将所有的坐标排序
    alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 去重
        /*unique 函数用于 移除相邻的重复元素,它并不真正删除元素,而是将重复的元素移动到容器的末尾部分,
    函数返回一个迭代器,该迭代器指向新容器末尾的下一个位置(即去重后第一个"无效"元素的位置)。
    前提条件:为了让 unique 正确工作,输入的容器必须是有序的,即相等的元素必须相邻。
    因此,在调用 unique 之前,通常要先对容器进行排序(sort)。
    alls.begin() 是 alls 数组的起始位置。
    alls.end() 是 alls 数组的末尾位置(不包括最后一个元素)。
    unique(alls.begin(), alls.end()) 将相邻的重复元素移动到容器末尾,
    并返回一个新的迭代器 new_end,该迭代器指向去重后有效数据的末尾。*/
    // 处理插入操作
    for (auto item : add)
    {
        int x = find(item.first); // 找到 x 在离散化后的索引
        a[x] += item.second;      // 在离散化后的位置上加上对应的值
    }
    // 计算前缀和
    for (int i = 1; i <= alls.size(); i++)
    {
        s[i] = s[i - 1] + a[i];  // 通过累加前缀和数组得到区间的和
    }
    // 处理查询操作
    for (auto item : query)
    {
        int l = find(item.first);  // 找到 l 在离散化后的索引
        int r = find(item.second); // 找到 r 在离散化后的索引
        cout << s[r] - s[l - 1] << endl; // 输出区间 [l, r] 的和,并换行
    }
    return 0;
}

离散化代码源码

相关推荐
半盏茶香20 分钟前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
哎呦,帅小伙哦28 分钟前
Effective C++ 规则41:了解隐式接口和编译期多态
c++·effective c++
CodeJourney.39 分钟前
小型分布式发电项目优化设计方案
算法
DARLING Zero two♡1 小时前
【初阶数据结构】逆流的回环链桥:双链表
c语言·数据结构·c++·链表·双链表
9毫米的幻想1 小时前
【Linux系统】—— 编译器 gcc/g++ 的使用
linux·运维·服务器·c语言·c++
带多刺的玫瑰1 小时前
Leecode刷题C语言之从栈中取出K个硬币的最大面积和
数据结构·算法·图论
Cando学算法1 小时前
Codeforces Round 1000 (Div. 2)(前三题)
数据结构·c++·算法
薯条不要番茄酱1 小时前
【动态规划】落花人独立,微雨燕双飞 - 8. 01背包问题
算法·动态规划
小林熬夜学编程1 小时前
【Python】第三弹---编程基础进阶:掌握输入输出与运算符的全面指南
开发语言·python·算法
字节高级特工1 小时前
【优选算法】5----有效三角形个数
c++·算法