揭秘C++ lower_bound自定义比较器:99%程序员忽略的关键细节

【C++】 详解 lower_bound 和 upper_bound 函数(看不懂来捶我!!!) 这两个函数是我在 LeetCode 上做题见到,看到不熟悉的函数 lower_bound 和 upper_bound让我感觉很难受,于是在C++ 官网去学习,例子就一个是最基础的,我看明白了。虽然是两个函数的接口就两个,但是有时候看别人使用的时候,里面参数还可以放不同的仿函数,我懵逼了。就去网上搜,但是大家讲解的都是它的第一个接口。我只能再把文档一遍一遍过,代码一遍遍的尝试,调试。最终通过查阅资料将其总结如下。 阅读详情

第一章:lower_bound自定义比较器的核心概念

在C++标准库中,`std::lower_bound` 是一个高效的二分查找算法,用于在**已排序序列**中寻找第一个不小于给定值的元素位置。其默认行为基于 `<` 运算符进行比较,但通过引入自定义比较器,可以灵活控制元素间的排序逻辑。

自定义比较器的作用

自定义比较器允许开发者定义特定的排序规则,适用于复杂数据类型或非标准排序需求。例如,在结构体数组中根据某一字段排序并查找时,必须提供相应的比较逻辑。

比较器的实现方式

比较器通常以函数对象、Lambda表达式或函数指针形式传入 `lower_bound`。关键要求是保持与排序顺序一致的严格弱序关系。
  • 比较器应返回布尔值,表示第一个参数是否“小于”第二个参数
  • 必须与容器的排序规则完全匹配,否则结果未定义
  • Lambda表达式是最简洁的实现方式之一
以下示例展示如何在结构体数组中使用自定义比较器:

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

struct Person {
    int age;
    std::string name;
};

int main() {
    std::vector<Person> people = {{25, "Alice"}, {30, "Bob"}, {35, "Charlie"}};
    
    // 使用Lambda作为比较器,按age字段排序
    auto cmp = [](const Person& a, const Person& b) {
        return a.age < b.age;  // 仅比较age字段
    };
    
    Person query{30, ""};
    auto it = std::lower_bound(people.begin(), people.end(), query, cmp);
    
    if (it != people.end()) {
        std::cout << "Found: " << it->name << std::endl;
    }
    return 0;
}
参数说明
first, last搜索范围的迭代器区间
value要查找的目标值
comp自定义比较函数或函数对象
正确使用自定义比较器是确保 `lower_bound` 正确性和性能的关键。

第二章:深入理解比较器的设计原理

2.1 比较器的语义要求与严格弱序规则

在实现排序算法或容器(如 `std::set`、`std::map`)时,比较器必须满足**严格弱序**(Strict Weak Ordering)的数学性质,否则行为未定义。
严格弱序的核心规则
一个有效的比较器 `comp(a, b)` 应满足:
  • 非自反性:`comp(a, a)` 必须为 false
  • 非对称性:若 `comp(a, b)` 为 true,则 `comp(b, a)` 必须为 false
  • 传递性:若 `comp(a, b)` 和 `comp(b, c)` 为 true,则 `comp(a, c)` 也必须为 true
  • 传递性不可比性:若 a 与 b 不可比,b 与 c 不可比,则 a 与 c 也不可比
代码示例:合法的比较器
bool compare(int a, int b) {
    return a < b;  // 满足严格弱序
}
该函数基于内置 `<` 运算符,天然满足所有规则。若使用自定义逻辑(如结构体比较),需手动确保上述性质成立。
违反后果
错误类型后果
非传递性排序结果混乱
自反性为真容器插入失败或崩溃

2.2 operator< 与自定义函数对象的一致性陷阱

在 C++ 的泛型编程中,使用 operator< 或自定义比较函数对象时,若两者语义不一致,可能导致未定义行为。例如,在 std::set 或排序算法中,比较逻辑必须满足严格弱序。
常见错误示例

struct Point {
    int x, y;
    bool operator<(const Point& p) const { return x < p.x; }
};

struct CompareY {
    bool operator()(const Point& a, const Point& b) const {
        return a.y < b.y;
    }
};
上述代码中,operator< 按 x 比较,而 CompareY 按 y 比较。若将 CompareY 用于依赖默认比较的容器,会导致元素排序混乱。
设计建议
  • 保持 operator< 与函数对象逻辑统一
  • 在容器声明中明确指定比较类型,避免隐式调用
  • 确保比较操作满足严格弱序:非自反、可传递、最多一方成立

2.3 lambda表达式作为比较器的生命周期问题

在Java集合排序中,lambda表达式常被用作临时比较器,例如:
list.sort((a, b) -> a.getAge() - b.getAge());
该lambda在每次调用时生成新的实例,但其生命周期仅绑定于当前排序操作。
内存与性能影响
频繁创建lambda比较器可能导致短期对象堆积,增加GC压力。尤其在循环或高频调用场景中,应考虑缓存复用:
  • 使用静态方法引用替代lambda以提升可重用性
  • 将常用比较逻辑提取为Comparator常量
闭包捕获的风险
若lambda引用外部变量,会形成闭包,延长变量生命周期,可能引发内存泄漏。建议避免在比较器中捕获可变状态。

2.4 多字段排序中的比较器逻辑构建

在处理复杂数据结构时,多字段排序是常见需求。构建合理的比较器逻辑,能确保数据按优先级顺序精确排列。
比较器设计原则
多字段排序需定义字段优先级。例如,先按姓名升序,再按年龄降序。每个字段的比较结果仅在前一字段相等时生效。
代码实现示例
type Person struct {
    Name string
    Age  int
}

sort.Slice(persons, func(i, j int) bool {
    if persons[i].Name != persons[j].Name {
        return persons[i].Name < persons[j].Name // 首字段:姓名升序
    }
    return persons[i].Age > persons[j].Age // 次字段:年龄降序
})
上述代码中,sort.Slice 接收一个切片和比较函数。当姓名不同时按姓名升序;相同时根据年龄降序排列,体现多级排序逻辑。

2.5 性能影响:内联优化与函数调用开销分析

函数调用虽是程序设计的基本构造,但伴随有栈帧创建、参数传递和返回跳转等开销。频繁的小函数调用可能成为性能瓶颈,尤其在热点路径中。
内联优化的作用
编译器通过内联(Inlining)将小函数体直接嵌入调用处,消除调用开销。这减少了指令跳转和栈操作,提升执行效率。

// 原始函数
func add(a, b int) int {
    return a + b
}

// 调用点经内联优化后等效为:
// result := 10 + 20
result := add(10, 20)
上述代码中,add 函数逻辑简单,编译器很可能将其内联,避免实际调用过程。
权衡与限制
过度内联会增加代码体积,影响指令缓存命中率。现代编译器基于成本模型自动决策,综合考虑函数大小、调用频率等因素。
  • 内联适用于短小、高频调用的函数
  • 递归函数或大型函数通常不被内联
  • 可使用编译指令(如 __inline__)建议内联行为

第三章:常见误用场景与解决方案

3.1 错误返回值定位:为何找不到“明明存在”的元素

在自动化测试或DOM操作中,常遇到“元素存在但无法定位”的问题。这通常源于查找时机不当或上下文环境错误。
常见原因分析
  • 页面异步加载导致元素尚未渲染完成
  • 目标元素位于 iframe 或 shadow DOM 中
  • 选择器拼写错误或动态 class 变化
代码示例与调试

// 错误写法:未等待元素加载
const element = document.getElementById('target');
console.log(element.textContent); // 报错:Cannot read property 'textContent'

// 正确做法:使用观察者模式等待元素出现
const observer = new MutationObserver(() => {
  const el = document.getElementById('target');
  if (el) {
    console.log('Found:', el.textContent);
    observer.disconnect();
  }
});
observer.observe(document.body, { childList: true, subtree: true });
上述代码通过 MutationObserver 监听 DOM 变化,避免在元素未生成前进行访问,有效解决时序问题。参数 childList: true 表示监听子节点增减,subtree: true 确保深层嵌套也能被捕获。

3.2 容器未排序或排序依据不一致导致的行为未定义

在并发编程中,若多个协程对共享容器进行读写操作而未保证排序一致性,可能导致行为未定义。典型场景包括未加锁的 map 并发访问。
并发访问示例

var data = make(map[int]int)
go func() { data[1] = 10 }()
go func() { _ = data[1] }() // 未定义行为
上述代码中,一个 goroutine 写入 map,另一个同时读取,违反了 Go 的并发安全规则,可能引发 panic 或数据损坏。
解决方案对比
方法安全性性能
sync.Mutex高中
sync.RWMutex高较高
sync.Map高高(读多写少)
使用读写锁或专为并发设计的 sync.Map 可避免此类问题,确保操作顺序一致性。

3.3 反向比较器与upper_bound的混淆使用

在使用STL算法时,开发者常误用反向比较器(如greater<>())与upper_bound的组合,导致查找逻辑出错。
常见错误场景
当容器按降序排列并使用greater<>()时,若未正确理解upper_bound的行为,会得到非预期结果:

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

int main() {
    std::vector<int> vec = {5, 4, 3, 2, 1}; // 降序
    auto it = std::upper_bound(vec.begin(), vec.end(), 3, std::greater<int>());
    std::cout << *it << "\n"; // 输出: 2
}
上述代码中,upper_bound在降序序列中寻找第一个“小于等于”目标值的元素。由于传入greater<>,其语义变为:找到第一个比3小的元素,即2。这与升序场景下的直觉相反。
正确理解语义
  • upper_bound依赖比较器定义“上界”
  • 使用greater时,等价于查找最后一个大于目标值的位置加一
  • 务必保证排序与查找使用的比较器一致

第四章:高级应用与工程实践

4.1 在结构体和类对象中实现可复用比较器

在面向对象编程中,结构体或类常用于封装数据。为了支持排序或集合操作,需为其定义可复用的比较逻辑。
定义通用比较接口
通过实现比较方法(如 `CompareTo` 或 `<=>`),可在对象内部封装比较规则,提升代码复用性。
Go 语言示例:结构体比较器

type Person struct {
    Name string
    Age  int
}

func (p Person) Compare(other Person) int {
    if p.Age < other.Age {
        return -1
    } else if p.Age > other.Age {
        return 1
    }
    return 0
}
该代码定义了基于年龄的比较逻辑,返回值符合标准比较约定:-1(小于)、0(相等)、1(大于),便于集成至排序算法。
  • 比较器应保持对称性和传递性
  • 避免直接暴露字段,建议通过方法访问
  • 支持多字段组合比较以增强灵活性

4.2 结合std::function与模板实现通用查找封装

在C++中,通过结合`std::function`与函数模板,可构建高度通用的查找接口。该方法将查找逻辑抽象为可调用对象,提升代码复用性。
泛型查找函数设计
使用模板参数接受任意容器类型,`std::function`作为匹配条件,实现解耦:

template<typename T>
const T* find_if(const std::vector<T>& container,
                std::function<bool(const T&)> predicate) {
    for (const auto& item : container) {
        if (predicate(item)) return &item;
    }
    return nullptr;
}
上述代码中,`predicate`封装判断逻辑,`container`支持任意`vector`类型。调用时可传入lambda、函数指针或仿函数。
使用场景示例
  • 按数值范围查找:如 `find_if(vec, [](int n){ return n > 10; });`
  • 对象属性匹配:如查找姓名字段符合条件的结构体
该模式将算法与数据类型、匹配条件彻底分离,具备良好的扩展性与可测试性。

4.3 多态比较器在复杂业务逻辑中的设计模式

在处理异构数据源的排序与匹配时,多态比较器通过接口抽象统一比较行为,支持运行时动态绑定具体策略。
策略注册机制
使用工厂模式管理不同类型的比较器实例:

public interface ComparatorStrategy {
    int compare(Object a, Object b);
}

public class DateComparator implements ComparatorStrategy {
    public int compare(Object a, Object b) {
        // 按时间戳排序逻辑
        return ((Date)a).compareTo((Date)b);
    }
}
上述代码定义了可扩展的比较接口,各实现类封装特定类型的比较规则,提升可维护性。
运行时调度表
数据类型比较器实现优先级权重
StringLexicographicComparator1
DoubleNumericComparator2
DateDateComparator3
通过类型识别自动选取最优比较器,实现业务规则与核心逻辑解耦。

4.4 调试技巧:断言验证比较器正确性

在实现自定义比较器时,确保其逻辑正确至关重要。使用断言(assertions)可以在开发阶段快速暴露排序或比较逻辑中的缺陷。
断言的基本用法
通过单元测试中的断言机制,验证比较器对各种输入的返回值是否符合预期:
func TestComparator(t *testing.T) {
    comparator := func(a, b int) int {
        if a < b { return -1 }
        if a > b { return 1 }
        return 0
    }

    // 断言相等情况
    assert.Equal(t, 0, comparator(5, 5))
    // 断言小于情况
    assert.Equal(t, -1, comparator(3, 7))
    // 断言大于情况
    assert.Equal(t, 1, comparator(9, 4))
}
上述代码中,comparator 函数需满足三向比较语义:负数表示小于,正数表示大于,零表示相等。每个断言验证一种关系,确保行为一致。
常见错误与检查清单
  • 避免溢出导致的符号反转(如直接做减法)
  • 确保对称性:若 a < b,则 b > a
  • 传递性:若 a < b 且 b < c,则 a < c

第五章:总结与最佳实践建议

监控与日志的统一管理
在微服务架构中,分散的日志增加了故障排查难度。推荐使用 ELK(Elasticsearch, Logstash, Kibana)或 Loki 统一收集日志。以下为 Docker 环境下日志驱动配置示例:
{
  "log-driver": "fluentd",
  "log-opts": {
    "fluentd-address": "http://fluentd-host:24224",
    "tag": "service-name-production"
  }
}
持续集成中的安全扫描
在 CI/CD 流程中嵌入安全检测工具可有效预防漏洞上线。建议在构建阶段加入如下步骤:
  • 使用 Trivy 扫描容器镜像中的 CVE 漏洞
  • 通过 SonarQube 分析代码质量与安全热点
  • 集成 OWASP ZAP 进行自动化渗透测试
资源配额与弹性策略配置
Kubernetes 集群中应为关键服务设置资源限制,避免“噪声邻居”问题。参考配置如下:
服务类型CPU 请求内存限制HPA 目标利用率
API 网关200m512Mi70%
订单处理300m768Mi65%
灰度发布实施要点
采用 Istio 实现基于用户标签的流量切分时,需确保目标服务具备版本标识。可通过以下方式注入用户上下文:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
spec:
  http:
  - match:
    - headers:
        x-user-tier:
          exact: premium
    route:
    - destination:
        host: checkout-service
        subset: v2
C++ Map深度解析:从红黑树原理到一对多映射实战 在C++编程中,关联容器是处理键值对数据的关键数据结构,它通过将键与值关联,实现了高效的数据查找与组织。其底层通常基于平衡二叉搜索树(如红黑树)实现,确保了元素的有序性和对数级别的操作复杂度,从而在需要范围查询或有序输出的场景中展现出独特价值。这种设计使得它在数据库索引、缓存系统和配置管理等场景广泛应用。本文聚焦于C++标准库中的`std::map`,深入探讨其基于红黑树的实现原理,并详细解析如何利用`std::map`与`std::vector`结合,优雅地实现**一对多映射**关系,例如管理班级学生列表 阅读详情

相关推荐

深入理解C++ STL Set:红黑树实现、性能优化与实战应用

在C++标准模板库中,关联容器是管理有序数据集合的核心组件,其底层通常基于平衡二叉搜索树实现,以确保元素自动排序和高效查找。红黑树作为一种自平衡二叉搜索树,通过严格的着色规则和旋转操作,保证了在最坏情况下插入、删除和查找操作的时间复杂度稳定在O(log n),从而在动态数据维护场景中提供了可靠的性能保障。这种数据结构的设计哲学在于抽象复杂的底层细节,为开发者提供简洁的接口,同时隐藏了节点调整的复杂性。在实际工程中,理解其原理有助于避免常见性能陷阱,例如利用insert返回值合并查找与插入操作,以及正确处理迭

weixin_34302561的博客 337

【C++学习记录】二分查找lower_bound()和upper_bound()中的自定义比较函数

在lc上刷题的时候遇到了upper_bound()自定义cmp的问题,遂记录下二者的区别。

OkizukiNanami的博客 1638

C++ STL set容器深度解析:从红黑树原理到高效应用实践

在C++编程中,关联容器是处理需要快速查找、去重和有序存储数据的关键数据结构。其核心原理基于高效的树形或哈希结构,能够在对数或常数时间内完成主要操作,为程序带来显著的性能提升。红黑树作为一种自平衡二叉搜索树,通过巧妙的着色规则维持大致平衡,在动态增删和查找之间取得了优异折衷,这正是std::set等有序容器的底层引擎。这种设计使得容器在游戏服务器玩家列表、金融交易数据实时排序、以及需要快速去重的数据处理引擎等场景中价值凸显。本文以std::set为焦点,深入探讨其基于红黑树的实现机制,并解析迭代器失效、自定

weixin_33976072的博客 443

lower_bound自定义比较器实战,彻底搞懂排序与查找的底层逻辑

掌握lower_bound的自定义比较器用法,解决复杂排序下的查找难题。详解STL底层逻辑、适用场景与二分查找优化技巧,提升算法效率。理解谓词设计原则,轻松应对非默认排序需求。lower_bound 的比较器实战解析,值得收藏。

StepNexus的博客 456

ACC-C++组初赛全攻略:考点拆解、备赛清单与赛场实战复盘

编程竞赛近年来已成为检验算法基础与代码实战能力的标尺,其中C++语言凭借高效的性能和丰富的标准库,成为参赛者的首选工具。对于初赛而言,题目往往不追求偏题怪题,而是通过数据范围、边界条件与时间复杂度陷阱,筛选出基础扎实、代码习惯良好的选手。常见考点集中在STL容器的底层机制、前缀和与二分查找的灵活运用、DFS与BFS的模板熟练度,以及对复杂度的准确估算。理解这些核心原理,不仅能解决比赛中的具体问题,更能提升日常工程实践中的算法设计能力。从初赛的题型分布到赛前的优先级备赛清单,再到赛场上的时间分配与错误排查,系

weixin_33911824的博客 146

C++高性能主题统计系统:零拷贝无锁实时计数方案

在高吞吐消息处理、IoT网关和金融行情分发等C++服务中,主题维度的实时统计是运维监控、流量建模与合规审计的核心能力。其本质是面向确定性场景(主题名有限、写入高频、查询低频)的轻量级指标采集问题,需兼顾纳秒级写入开销、线程安全、内存可控与滑动窗口精度。传统方案如Prometheus client_cpp或OpenTelemetry C++ SDK因字符串序列化、动态内存分配和定时器调度引入显著延迟与抖动。本文聚焦‘零拷贝采集’与‘无锁聚合’两大关键技术路径,通过双层哈希映射(静态ID预分配+string_v

weixin_34245749的博客 414

C++ 折半查找之 lower_bound 和 upper_bound

C++ 折半查找之 lower_bound 和 upper_bound

qq_42303573的博客 7282

Ubuntu安装opencv4.5(自己安装过程详细)

1.下载opencv 在opencv官网下载source版,下载链接 http://opencv.org/releases.html。别下载错版本 下载过程就不多说了。 2.安装过程 2.1解压 unzip opencv-4.5.0.zip cd opencv-4.5.0 2.2安装依赖的库 sudo apt-get install cmake sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-

weixin_45629790的博客 1万+

C++ upper_bound()和lower_bound()(二分查找中使用)的定义,使用方法和区别

C++ upper_bound()和lower_bound()(二分查找中使用)的定义,使用方法和区别

Sansipi的博客 7266

脑电分析:为什么大脑信号会“变同步”?——事件相关同步化与去同步化 (ERS/ERD) 全景解析

脑电分析中的事件相关同步化(ERS)和去同步化(ERD)是研究大脑动态节律的重要方法,反映特定任务下脑电频段能量的变化。ERD表示神经元活动分散(功率下降),提示脑区活跃处理信息;ERS则反映神经元同步(功率增强),常与静息状态相关。本文详解了ERS/ERD的生理机制、计算流程(包括基线校正和功率谱分析),并提供了Python实现示例,展示如何通过Welch法和STFT进行时频分析,生成ERD/ERS热力图。该技术广泛应用于运动想象脑机接口、癫痫检测等领域,为理解大脑功能状态提供了量化工具。

qq_32516809的博客 1396

详解Agent Skills:让AI拥有更多专业能力(什么是Agent Skills?如何创建?如何使用?如何获取?)

本文分享如何将零散指令沉淀为可复用的 AI 能力模块🧩,介绍什么是Agent Skills?如何创建?如何获取?📚

XiaoqiangClub的博客 1270

揭秘C++ map::lower_bound:99%程序员忽略的关键细节与最佳实践

掌握C++ STL map 的 lower_bound,精准定位键值插入位置,提升查找效率。详解其与upper_bound区别、在有序容器中的典型应用及性能优势,避免常见误区。核心技巧解析,值得收藏。

ByteChat的博客 825

【27】软考软件设计师——数据流图(DFD)补全题满分精讲|下午15分大题深度拆解

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第27篇,深度精讲**下午案例题第1道必考大题:数据流图(DFD)补全**,该题单题分值高达**12 ~ 15分**,是整张试卷最稳的保底得分大题。我结合多年备考复盘与真题阅卷规则,超详细拆解DFD四大核心元素标准定义、机考绘图规范、三层分层逻辑、**父图子图平衡刚性扣分规则**,升级强化版「DFD满分补全三步法」;复刻历年高频真题完整流程,拆解缺失数据流定位、实体/存储辨析、平衡改错、文字需求对照全流程,配套**阅卷满分答题话术、机考避坑细则

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 590

map / set 完全指南:红黑树与有序容器

有序容器真正让人舍不得放弃的能力是范围查询(第一个 ≥ key)、(第一个 > key)、(一次拿到两者,也就是// map_range.cpp — 编译: g++ -std=c++17 -Wall -O2 map_range.cpp -o map_range// 踩坑用的比较器:只按字符串长度比较// 第一个 >= 20// 第一个 > 30it!= hi;// 一次拿到上下界it!= al;// 与 "ab" 等价(长度相同)→ 不新增条目。

weixin_38244193的博客 468

《囚徒健身》 六艺,十式

文章目录《囚徒健身》 六艺,十式1、六艺,十式2、优缺点3、手臂和上半身 《囚徒健身》 六艺,十式 1、六艺,十式 1、俯卧撑: 2、深蹲: 3、举腿: 4、引体向上: 5、桥: 6、倒立撑: 十式就是每个动作分拆为十个不同的动作等级,进行训练 每一式里面,又根据做的组数和个数,分成三层,初级,中级,高级 依次循序渐进,每完成上一个动作的高级,则向下一个动作前进 2、优缺点 优点 : 六个动作都是很常见的,日常的动作,不太需要依赖什么器械,随时随地都可以练习,很方便 这些动作可以覆盖到全身大部分

简简单单Onlinezuozuo 4564

高级数据结构之R树(R-tree)

R树(R-tree)是一种将B树扩展到多维情况下得到的数据结构,它最初由Antonin Guttman于1984年提出。B树的结点中会存储一个键的集合,这些键把线分成片段,沿着那条线的点仅属于一个片段。因此,B树使得我们可以很容易地找到点。如果把沿线各处的点表示成B树结点,我们就能够确定点所属唯一子结点,在那里可以找到该点。 Antonin Guttman在他提出R树的经典论文中给出的R树例子...

白马负金羁 1万+

C++ std::map深度剖析:从红黑树原理到工程实践避坑指南

在C++开发中,关联容器是处理键值对存储与高效查找的基础工具。std::map作为标准库中的有序关联容器,底层基于红黑树实现,能够在插入、删除、查找操作上稳定提供O(log n)的时间复杂度,这是哈希容器无序且可能退化的短板所不具备的优势。理解其有序性、节点内存模型以及迭代器失效规则,有助于开发者在实际项目中做出合理的容器选型。无论是利用lower_bound与upper_bound完成区间查询,还是通过extract实现无拷贝节点转移,这些高级用法都能显著提升代码质量。本文围绕std::map的核心原理、

weixin_34198881的博客 368

R语言中5种正态性检验的方法

统计学中的t检验和方差分析等方法的应用条件是样本都来自正态总体或近似正态总体,只有符合这个条件,才能用这些方法来检验各样本所属的总体参数的差异显著性。文本向大家介绍在R语言中检验正态性的几种方法: 1、Kolmogorov-Smirnov检验 K-S检验检验单一样本是否来自某一特定分布。比如检验一组数据是否为正态分布。它的检验方法是以样本数据的累积频数分布与特定理论分布比较,若两者间的差距很小,则推论该样本取自某特定分布族。K-S检验的原假设和备择假设为: H0:样本所来自的总体分布服从

Mrrunsen的博客 2万+

C++ std::map 原理与实战:红黑树、键值对、选型避坑

在 C++ 标准库中,关联容器用于通过键快速定位值,std::map 是其中的有序实现,核心是键值对存储与基于红黑树的动态平衡。红黑树保证查找、插入、删除维持 O(log n) 的稳定复杂度,并让元素按键升序组织,从而支持范围查询、最值访问和有序遍历。其工程价值在于把手工数组扫描替换为可预测的高效索引,适合词频统计、有序字典与区间统计等场景。与 unordered_map 相比,std::map 以有序性和迭代器稳定性换取可预期行为;与 vector 相比,它更擅长高频查找但遍历缓存不占优。理解键必须可比较

weixin_34005042的博客 420

利用XGBoost实现短期电力负荷预测

本数据集为某地区2009年-2015年的用电负荷,时间片为每分钟这里我们定义了XGB模型作为实例,来进行模型训练,之后我们会对其使用网格搜索找到最优的参数。

优快云 精品推荐 4495

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++ 查找算法:std::find 与容器成员 find 的性能差距

查找族算法的统一契约是「返回迭代器,找不到返回last,永远和end()比any_ofall_ofnone_of会短路,判断「有没有」优先用它们而不是count;算法只看得见迭代器、看不见容器,所以在mapset上做 key 查找必须用容器成员函数,std::find上去就是 O(n);元素很少且内存连续时,线性扫描的缓存优势反而可能赢过树,选型要看 N 而不是背复杂度。

weixin_38244193的博客 640

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C++ STL map/set底层实现:红黑树封装与核心原理详解

在C++编程中,关联容器是解决高效查找与键值映射问题的核心数据结构。其底层通常基于平衡二叉搜索树(如红黑树)实现,通过维护元素的有序性,确保插入、删除和查找操作的时间复杂度稳定在O(log n)。这种设计不仅提供了稳定的性能保障,还支持高效的范围查询和有序遍历,在字典、缓存、去重等场景中具有重要技术价值。理解其封装原理,特别是迭代器设计、模板应用和内存管理,是深入掌握STL的关键。本文以红黑树为例,剖析map和set的底层实现,探讨自定义比较器、异常安全等工程实践问题,帮助开发者从API使用者转变为容器设计

weixin_34101229的博客 322

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C++ STL set容器深度解析:从红黑树原理到实战性能优化

在C++编程中,数据结构的选择直接影响程序的性能和可维护性。关联容器通过键值对元素进行组织,提供了高效的查找和访问能力。其底层通常基于平衡二叉搜索树(如红黑树)实现,确保了插入、删除和查找操作的对数时间复杂度稳定性,避免了哈希表在最坏情况下的性能退化。这种设计在需要元素有序性、确定性性能以及范围查询的场景下具有重要价值,例如维护用户ID列表、实现排行榜或进行数据去重。本文聚焦于C++标准库中的set容器,深入探讨其基于红黑树的实现原理,并通过对比vector和unordered_set,分析其性能边界与适用

weixin_34068198的博客 380

10.list【由浅入深-C++】

通过本章的学习,我们明确了list的定位:它在主流实现中通常采用带哨兵节点的双向循环链表,牺牲了随机访问能力,换取了在已知位置迭代器时高效的节点插入与删除。但作为一个追求底层的 C++ 学习者,仅仅会调用接口是远远不够的。list的迭代器是如何封装指针,从而重载++和操作的?和iterator如何复用同一份代码?如何手动管理节点内存?在下一章中,我们将深入源码,从零开始模拟实现一个简易版的 list,彻底揭开它底层的面纱。操作场景size_t pos(整数索引)iterator(迭代器)设计哲学。

插花弄玉的博客 566

C++ vector容器完全指南:从原理到性能优化实战

在C++标准模板库(STL)中,容器是组织和存储数据的核心组件,其设计遵循了抽象、通用和高性能的原则。动态数组作为最基本的数据结构之一,因其内存连续性和随机访问的高效性而被广泛应用。vector容器正是这一原理的工程实现,它通过自动管理内存容量和提供丰富的接口,解决了原生数组固定大小的痛点,其技术价值在于平衡了开发效率与运行时性能。在实际应用中,无论是算法实现、游戏开发还是服务器编程,vector都是处理序列数据的首选。本文深入解析了vector的动态增长机制、迭代器失效问题以及性能优化策略,并探讨了其与l

weixin_30376083的博客 533

星图识别的C++工程实现:从球面几何到嵌入式实时处理

星图识别是航天器自主导航的核心技术,本质是将天球坐标系下的恒星空间关系转化为可计算的几何约束问题。其原理依赖球面三角学建模,通过角距不变性构建尺度与旋转鲁棒的三角形特征;技术价值在于突破图像匹配范式,在资源受限环境下实现高精度、低延迟的姿态解算。典型应用场景包括卫星星敏感器、深空探测器自主定姿及嵌入式导航模块开发。本文聚焦C++底层实现,涵盖球面距离计算、归一化边长比特征设计、内存池优化与ARM平台实时调度等关键实践,直击天体导航中‘物理约束→算法设计→工程落地’的全链路难点。

weixin_30420305的博客 422
上一篇: 【C++专家私藏笔记】:函数重载参数精确匹配与类型提升的终极指南
下一篇: 原始字符串转义还在踩坑?C# 11这5大改进让你效率翻倍
QuickDebug
博客等级 码龄1年 152粉丝 2013原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值