离散化C++

news/2025/2/2 1:25:36 标签: c++, 开发语言

离散化(Discretization)是一种将连续数据映射到离散值的技术,常用于将大数据范围压缩到较小范围,例如将数值映射到索引。离散化在算法竞赛中常用于处理数值范围较大但数据量较小的问题(如区间问题、统计问题等)。

以下是离散化的模板和示例:


1. 离散化的基本步骤

  1. 排序:将所有需要离散化的值排序。
  2. 去重:去除重复的值。
  3. 映射:通过二分查找将原始值映射到离散化后的索引。

2. 离散化模板

2.1 使用 std::vectorstd::unique

#include <iostream>
#include <vector>
#include <algorithm>

// 离散化函数
std::vector<int> discretize(std::vector<int>& nums) {
    // 1. 排序
    std::vector<int> sorted_nums = nums;
    std::sort(sorted_nums.begin(), sorted_nums.end());

    // 2. 去重
    auto last = std::unique(sorted_nums.begin(), sorted_nums.end());
    sorted_nums.erase(last, sorted_nums.end());

    // 3. 映射
    std::vector<int> result(nums.size());
    for (size_t i = 0; i < nums.size(); i++) {
        result[i] = std::lower_bound(sorted_nums.begin(), sorted_nums.end(), nums[i]) - sorted_nums.begin();
    }

    return result;
}

int main() {
    std::vector<int> nums = {100, 200, 50, 100, 300, 50};

    // 离散化
    std::vector<int> discretized = discretize(nums);

    // 输出结果
    std::cout << "Original: ";
    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    std::cout << "Discretized: ";
    for (int num : discretized) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Original: 100 200 50 100 300 50 
Discretized: 1 2 0 1 3 0 

2.2 离散化后还原原始值

如果需要还原离散化后的值,可以通过离散化数组进行映射。

#include <iostream>
#include <vector>
#include <algorithm>

// 离散化函数
std::pair<std::vector<int>, std::vector<int>> discretizeWithMap(std::vector<int>& nums) {
    // 1. 排序
    std::vector<int> sorted_nums = nums;
    std::sort(sorted_nums.begin(), sorted_nums.end());

    // 2. 去重
    auto last = std::unique(sorted_nums.begin(), sorted_nums.end());
    sorted_nums.erase(last, sorted_nums.end());

    // 3. 映射
    std::vector<int> result(nums.size());
    for (size_t i = 0; i < nums.size(); i++) {
        result[i] = std::lower_bound(sorted_nums.begin(), sorted_nums.end(), nums[i]) - sorted_nums.begin();
    }

    return {result, sorted_nums};
}

int main() {
    std::vector<int> nums = {100, 200, 50, 100, 300, 50};

    // 离散化
    auto [discretized, map] = discretizeWithMap(nums);

    // 输出结果
    std::cout << "Original: ";
    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    std::cout << "Discretized: ";
    for (int num : discretized) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    std::cout << "Map: ";
    for (int num : map) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 还原离散化后的值
    std::cout << "Reconstructed: ";
    for (int num : discretized) {
        std::cout << map[num] << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Original: 100 200 50 100 300 50 
Discretized: 1 2 0 1 3 0 
Map: 50 100 200 300 
Reconstructed: 100 200 50 100 300 50 

3. 离散化的应用场景

3.1 区间问题

离散化常用于处理区间问题,例如区间合并、区间查询等。

#include <iostream>
#include <vector>
#include <algorithm>

// 区间合并
std::vector<std::pair<int, int>> mergeIntervals(std::vector<std::pair<int, int>>& intervals) {
    if (intervals.empty()) return {};

    // 离散化
    std::vector<int> nums;
    for (const auto& interval : intervals) {
        nums.push_back(interval.first);
        nums.push_back(interval.second);
    }
    auto [discretized, map] = discretizeWithMap(nums);

    // 区间合并
    std::sort(intervals.begin(), intervals.end());
    std::vector<std::pair<int, int>> merged;
    for (const auto& interval : intervals) {
        if (merged.empty() || merged.back().second < interval.first) {
            merged.push_back(interval);
        } else {
            merged.back().second = std::max(merged.back().second, interval.second);
        }
    }

    return merged;
}

int main() {
    std::vector<std::pair<int, int>> intervals = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};

    // 区间合并
    auto merged = mergeIntervals(intervals);

    // 输出结果
    std::cout << "Merged Intervals: ";
    for (const auto& interval : merged) {
        std::cout << "[" << interval.first << ", " << interval.second << "] ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Merged Intervals: [1, 6] [8, 10] [15, 18] 

3.2 统计问题

离散化可以用于统计某个范围内数据的频率。

#include <iostream>
#include <vector>
#include <algorithm>

// 统计频率
std::vector<int> countFrequency(std::vector<int>& nums) {
    // 离散化
    auto [discretized, map] = discretizeWithMap(nums);

    // 统计频率
    std::vector<int> freq(map.size(), 0);
    for (int num : discretized) {
        freq[num]++;
    }

    return freq;
}

int main() {
    std::vector<int> nums = {100, 200, 50, 100, 300, 50};

    // 统计频率
    auto freq = countFrequency(nums);

    // 输出结果
    std::cout << "Frequency: ";
    for (int count : freq) {
        std::cout << count << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出:

Frequency: 2 2 1 1 

4. 总结

  • 离散化的核心步骤是排序、去重和映射。
  • 离散化可以用于处理区间问题、统计问题等。
  • 通过离散化,可以将大数据范围压缩到较小范围,提高算法效率。

http://www.niftyadmin.cn/n/5839686.html

相关文章

JMeter中常见的四种参数化实现方式是什么?_file test_params

2 参数化实现 2.1 CSV Data Set Config 在JMeter中提起参数化&#xff0c;我们默认就想到CSV Data Set Config&#xff08;以下简称CSV&#xff09;&#xff0c;CSV能够读取文件中的数据并生成变量&#xff0c;被JMeter脚本引用&#xff0c;从而实现参数化。下面我们来详细探究…

S4 HANA税码科目确定(OB40)

本文主要介绍在S4 HANA OP中税码科目确定(OB40)相关设置。具体请参照如下内容&#xff1a; 税码科目确定(OB40) 在以上界面维护“Transaction Key”的记账码。 在以上界面进一步维护“Transaction Key”确定科目的规则。 Chart of Account:用于明确该规则适用于什么科目表。 …

Python 列表(使用列表时避免索引错误)

你将学习列表是什么以及如何使用列表元素。列表让你能够在一个地方存储成组的信息&#xff0c;其中可以只包含几个元素&#xff0c;也可以包含数百万个元素。 列表是新手可直接使用的最强大的Python功能之一&#xff0c;它融合了众多重要的编程概念。 使用列表时避免索引错误 …

mysql中in和exists的区别?

大家好&#xff0c;我是锋哥。今天分享关于【mysql中in和exists的区别&#xff1f;】面试题。希望对大家有帮助&#xff1b; mysql中in和exists的区别&#xff1f; 在 MySQL 中&#xff0c;IN 和 EXISTS 都是用于子查询的操作符&#xff0c;但它们在执行原理和适用场景上有所不…

Janus-Pro 论文解读:DeepSeek 如何重塑多模态技术格局

Janus-Pro&#xff1a;多模态领域的璀璨新星——技术解读与深度剖析 一、引言 在人工智能的浩瀚星空中&#xff0c;多模态理解与生成模型犹如耀眼的星座&#xff0c;不断推动着技术边界的拓展。Janus-Pro作为这一领域的新兴力量&#xff0c;以其卓越的性能和创新的架构&#x…

加一(66)

66. 加一 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:vector<int> plusOne(vector<int>& digits) {bool plus_one true;for (int i digits.size() - 1; i > 0; --i) {if (plus_one) {int tmp digits[i] 1;if …

pytorch逻辑回归实现垃圾邮件检测

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 完整代码&#xff1a; import torch import torch.nn as nn import torch.optim as optim from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split …

机器学习周报-文献阅读

文章目录 摘要Abstract 1 相关知识1.1 WDN建模1.2 掩码操作&#xff08;Masking Operation&#xff09; 2 论文内容2.1 WDN信息的数据处理2.2 使用所收集的数据构造模型2.2.1 Gated graph neural network2.2.2 Masking operation2.2.3 Training loss2.2.4 Evaluation metrics 2…