C++ STL之排列组合与洗牌详解:从使用到底层,再到面试八股

用Seurat和ComplexHeatmap绘制单细胞marker基因热图:从数据处理到可视化全流程 本文详细介绍了使用Seurat和ComplexHeatmap绘制单细胞marker基因热图的全流程,涵盖从数据处理、基因筛选、平均表达矩阵计算到高级可视化与注释添加。重点解析了如何利用ComplexHeatmap生成发表级热图,并整合热词信息,解决单细胞数据可视化中的常见问题,提升科研图表质量。 阅读详情

C++ STL之排列组合与洗牌详解:从使用到底层,再到面试八股

本文面向面试和日常开发,先讲调用,再讲原理,最后给口语化面试答案。


一、用法速查

1.1 std::next_permutation / std::prev_permutation —— 字典序排列

两个函数将序列原地变换为字典序的下一个/上一个排列。若存在则返回 true,若已是最后一个/第一个则返回 false 并将序列重置为最小/最大排列。

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v{1, 2, 3};

    // 生成所有全排列——1 2 3, 1 3 2, 2 1 3, 2 3 1, 3 1 2, 3 2 1
    do {
        for (int x : v) cout << x << " ";
        cout << "\n";
    } while (next_permutation(v.begin(), v.end()));

    // prev_permutation 用法相同,方向相反
    v = {3, 2, 1};
    do {
        for (int x : v) cout << x << " ";  // 3 2 1, 3 1 2, 2 3 1, 2 1 3, 1 3 2, 1 2 3
        cout << "\n";
    } while (prev_permutation(v.begin(), v.end()));
}

注意事项:

  • 要求输入序列已按目标顺序排列——生成全排列前必须先 sort 成升序再用 next_permutation,或用 sort(..., greater{}) 后配合 prev_permutation。
  • 相等元素不会交换,所以 {1, 1, 2} 只会生成 3 种排列而非 6 种。

1.2 std::shuffle —— 真随机洗牌(C++11)

用统一的随机数生成器(URNG)对序列执行均匀随机重排,O(n)。

#include <algorithm>
#include <random>
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 标准写法:random_device 获取种子,mt19937 做引擎
    shuffle(v.begin(), v.end(), mt19937{random_device{}()});

    for (int x : v) cout << x << " ";   // 每次运行结果不同
    cout << "\n";
}

关键点:

  • 第三个参数要求均匀随机位生成器(URNG),不满足 UniformRandomBitGenerator 要求的类型无法通过编译。
  • 每次 shuffle 的随机性完全取决于 URNG 的质量。

1.3 std::random_shuffle —— 已被移除(C++14 弃用,C++17 移除)

// C++11 中有两个重载:
// random_shuffle(first, last);                     // 使用 rand()
// random_shuffle(first, last, RandomFunc&&);       // 自定义随机函数

// 两个重载都在 C++14 被标记 deprecated,C++17 正式移除

移除原因:

  • 第一个重载固定使用 std::rand(),全局状态不可控、周期短(RAND_MAX 通常只有 32767)。
  • 第二个重载容易写出不均匀的随机函数(rand() % n 有模偏差)。
  • C++11 有了 <random> 标准库后,std::shuffle 是替代方案。

1.4 std::sample —— 无放回采样(C++17)

从输入范围中均匀随机选取 k 个元素写入输出迭代器,不修改输入。返回类型为 OutputIt(指向输出范围末尾),而非 void。

#include <algorithm>
#include <random>
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> pool{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    vector<int> result;

    // 从 pool 中无放回地随机抽取 3 个
    sample(pool.begin(), pool.end(), back_inserter(result), 3,
           mt19937{random_device{}()});

    for (int x : result) cout << x << " ";
    cout << "\n";
}

性能保证:O(n),只遍历输入一次。

1.5 快速查表

函数作用返回复杂度C++ 版本
next_permutation字典序下一个排列boolO(n) amortizedC++98
prev_permutation字典序上一个排列boolO(n) amortizedC++98
shuffle均匀随机重排voidO(n)C++11
random_shuffle随机重排(已移除)voidO(n)C++98 → 弃用
sample无放回采样OutputItO(n)C++17

二、底层原理

2.1 next_permutation 的四步算法

next_permutation 的核心思想是从右向左找第一个可以"增大"的位置,然后做最小幅度的调整。这是生成字典序下一个排列的经典算法,由 Donald Knuth 在 TAOCP 中给出:

  1. 从右向左找到第一个相邻升序对 (i, j),其中 j = i+1 且 *i < *j。如果找不到,说明序列已是最大排列(完全降序)。
  2. 从右向左找到第一个大于 *i 的元素 *k(由于步骤 1 保证了 [j, last) 是降序的,这一步一定能找到)。
  3. 交换 *i 和 *k(将字典序增加一步)。
  4. 反转 [j, last)(把后半段从降序变成升序,保证"最小增幅")。

否

是

从右向左找相邻升序对

找到?

已是最大排列
反转整个序列

从右找第一个大于 i 的元素 K

交换 i 和 K

反转 i 之后的区间

返回 true

举例 {1, 2, 3} → {1, 3, 2} 的过程:

  • 从右往左,2 < 3,所以 i=1(指向2),j=2(指向3)。
  • 从右往左找第一个大于 *i=2 的,找到 *k=3。
  • 交换 2 和 3 → {1, 3, 2}。
  • 反转 [j, last) → 此时 j 已到末尾,反转空区间 → {1, 3, 2}。

每一步的 amortized O(1) 复杂度来源于:相邻排列之间只有常数个元素被移动。

2.2 prev_permutation —— 对称操作

prev_permutation 是 next_permutation 的镜像操作,找的是字典序的上一个排列:

  1. 从右向左找第一个相邻降序对 (i, j),其中 *i > *j。
  2. 从右向左找第一个小于 *i 的 *k。
  3. 交换 *i 和 *k。
  4. 反转 [j, last)(将后半段从升序变回降序)。

如果步骤 1 找不到降序对,说明已是第一排列(完全升序),返回 false 并反转成全降序。

2.3 Fisher-Yates / Knuth Shuffle

std::shuffle 的标准实现是 Fisher-Yates 洗牌算法(也称 Knuth Shuffle),从后往前遍历,每个位置与当前位置之前的随机位置交换:

// 简化实现——std::shuffle 的等价逻辑
template<class RandomIt, class URNG>
void shuffle(RandomIt first, RandomIt last, URNG&& g) {
    for (auto i = last - 1; i > first; --i) {
        // 从 [first, i] 中均匀选取一个位置
        auto k = first + uniform_int_distribution<>(0, i - first)(g);
        iter_swap(i, k);
    }
}

否

是

i = n-1

i > 0 ?

结束,完成洗牌

在 [0, i] 中均匀随机选 k

交换 v[i] 与 v[k]

i--

为什么是真正的均匀随机:

  • 对于 n 个元素,每个排列出现的概率恰好是 1/n!。
  • 第 1 轮(最后一位):从 n 个中均匀选 1 个放末尾,概率 1/n。
  • 第 2 轮(倒数第二位):从剩余 n-1 个中均匀选 1 个,概率 1/(n-1)。
  • … 最终联合概率 1/n × 1/(n-1) × ... × 1/1 = 1/n!。

与 random_shuffle 的根本区别在于随机源的质量——shuffle 使用标准 <random> 库的 URNG,避免了 rand() 的周期短和模偏差问题。

2.4 std::sample 的实现——水塘抽样(Reservoir Sampling)

std::sample 在 C++17 标准中要求"每轮抽样的概率均匀"。当输入范围是 ForwardIterator 时,标准实现采用 水塘抽样(Reservoir Sampling) 算法,特别是 Algorithm R:

// 简化实现——水塘抽样(Algorithm R)
template<class InputIt, class OutputIt, class URNG>
OutputIt sample(InputIt first, InputIt last, OutputIt out,
                size_t k, URNG&& g) {
    using dist_t = uniform_int_distribution<size_t>;

    vector<decltype(*first)> reservoir;
    reservoir.reserve(k);

    // 阶段1:填充水塘——取前 k 个元素
    auto it = first;
    for (size_t i = 0; i < k; ++i, ++it) {
        if (it == last) {           // 不足 k 个,全取返回
            return copy(reservoir.begin(), reservoir.end(), out);
        }
        reservoir.push_back(*it);
    }

    // 阶段2:替换——对第 i 个元素 (i >= k),以 k/(i+1) 的概率替换到水塘中
    for (size_t i = k; it != last; ++it, ++i) {
        auto j = dist_t{0, i}(g);   // [0, i] 均匀随机
        if (j < k) reservoir[j] = *it;  // 替换水塘中的第 j 个
    }

    return copy(reservoir.begin(), reservoir.end(), out);
}

是

否,第 i 个

是

否

前 k 个直接入水塘

i = k

遍历到末尾?

输出水塘
返回 out

随机 j ∈ [0, i]

j < k ?

替换水塘中第 j 个

跳过

i++

关键设计:

  • O(n) 时间复杂度:只遍历输入一次,每个元素决定是否进入水塘。
  • O(k) 额外空间:只需要一个大小 k 的缓存区。
  • 均匀性证明:对于输入流中的任意位置 i(从 0 计数),它最终留在水塘中的概率是 k / (i+1) × (1 - 1/(i+2)) × ... = k/n。
  • 如果传入的是 RandomAccessIterator,某些实现会用更高效的 Selection Sampling,不需要 O(k) 额外空间。

三、面试题 + 口语化答案

Q1:手写 next_permutation

"标准库实现可以分为四步。先解释思路:找第一个升序对、找交换位置、交换、反转后半。面试时可以写简化版,注意处理返回 false 的情况时要逆序还原。

bool next_permutation(vector<int>& v) {
    int n = v.size();
    int i = n - 2;
    // 1. 从右找第一个 *i < *j
    while (i >= 0 && v[i] >= v[i + 1]) --i;
    if (i < 0) {
        reverse(v.begin(), v.end());
        return false;
    }
    // 2. 从右找第一个 > *i 的 *k
    int k = n - 1;
    while (v[k] <= v[i]) --k;
    // 3. 交换
    swap(v[i], v[k]);
    // 4. 反转后半
    reverse(v.begin() + i + 1, v.end());
    return true;
}

注意严格大于和大于等于的区分——处理重复元素时要用 >= / <=,否则会跳过或漏掉一些排列。"

Q2:全排列的时间复杂度是多少?

“n! 种排列,调用 n! 次 next_permutation,每次分摊 O(1),所以生成全部排列的时间是 O(n!)。空间 O(1),在输入序列上原地操作,不需要额外内存来存排列。这个复杂度是硬性的——n = 12 时 4.79 亿次,已经跑不完了,所以真写全排列的时候数据量不会太大。”

Q3:shuffle 和 random_shuffle 有什么区别?

“random_shuffle 被移除了,两个核心缺陷:一是默认用 rand(),RAND_MAX 通常 32767,序列稍长就会不均匀;二是模运算 rand() % n 在 n 不是 RAND_MAX 的约数时有模偏差。shuffle 用 <random> 库的 mt19937 配合 uniform_int_distribution,周期 2^19937-1,且分布模板直接给出均匀整数——这两个问题同时解决。所以 C++17 起只有 shuffle。”

Q4:随机数引擎怎么选?mt19937 还是 default_random_engine?

“面试问到就说 mt19937。它是 Mersenne Twister 算法,周期 2^19937-1,质量经过充分验证,是通用场景的首选。default_random_engine 是实现的别名——gcc 用 minstd_rand0,clang 用 mt19937,MSVC 用 mt19937。不同编译器行为不同,不可移植。跨平台要确定性的场景必须显式指定引擎类型,不要用 default_random_engine。”

Q5:std::sample 的时间复杂度和空间复杂度?返回类型是什么?

“时间 O(n),只遍历一次输入序列。空间 O(k),需要一个大小为 k 的水塘缓冲区。注意 sample 的返回类型是 OutputIt(指向输出范围末尾),不是 void——很多面试者会记错这一点。如果输入是 RandomAccessIterator,某些实现可以用 Selection Sampling 做到 O(k) 额外空间,但时间同样是 O(n)。采样数量 k 不能超过输入大小,超过时 sample 不会报错,会直接取完所有元素。”

Q6:水塘抽样(Reservoir Sampling)的原理是什么?

“水塘抽样解决的是’未知长度的数据流中均匀取 k 个’的问题。前 k 个元素直接进池子;对第 i(i ≥ k)个元素,以 k/(i+1) 的概率替换水塘中的一个随机位置。数学归纳可以证明每个元素最终留在池子里的概率都是 k/n。这个算法的精妙之处在于它只需要 O(n) 的遍历和 O(k) 的内存,且事先不需要知道 n。”

Q7:输入有重复元素时 next_permutation 怎么工作?

“它不会生成重复排列。比较时使用 *i < *j 和 *i < *k 的严格语义——注意不是 <=。所以 {1, 1, 2} 用 do-while 循环只输出 3 种排列而不是 6 种。这是设计上的有意选择:按字典序,重复元素在排列中的相对位置固定,减少了不必要的排列数量。如果需要全排列包含重复元素,可以先转换成带 index 的 pair 再排列。”

Q8:prev_permutation 怎么从对称性理解?

“和 next_permutation 是镜像操作。next 找升序对、交换较大元素、反转降序段为升序;prev 找降序对、交换较小元素、反转升序段为降序。从代码结构上看,把 next 的所有比较符取反(< 变 >,> 变 <)就是 prev。实际上标准库实现经常把两个函数做对称实现,内部只差一个比较器的方向选择。”


一句话总结:next_permutation 的四步找升序对→交换→反转算法和 shuffle 背后的 Fisher-Yates 洗牌是两大经典原地算法,分别对应"有序生成"和"无序打乱"两个方向;std::sample 的水塘抽样则解决了流式数据中均匀采样的问题——三者加起来覆盖了排列、洗牌、采样三个最常见的随机化操作场景。

【智能车Code review】——小S与中S道路判断 基本思想: 找到中线的左拐点和右拐点,并且计算出两点之间的空间距离。通过限制空间距离,分为中S和小S。 注意这种情况:当20行以下的中线斜率比较陡,此时可以通过人为限制设定,将第0行的中线设置为拐点。 if (flag_centre_right_point == 0 && flag_centre_left_point == 1 && parameterB >= 0.5 && centre_left_point[0] >= 33) { . 阅读详情

相关推荐

第一章 Cheat Enginee(CE)使用指南

Cheat Engine核心功能详细说明(以植物大战僵尸为例) 教你修改单机游戏。

m0_74545731的博客 1万+

C++排列算法深度解析:从标准库实现到高阶应用实战

排列是组合数学与算法设计中的基础概念,指将一组元素按特定顺序重新安排。其核心原理在于通过系统性的交换或选择,遍历所有可能的顺序组合,通常涉及递归、回溯或字典序生成策略。掌握排列算法对于理解算法复杂度、状态空间搜索及组合优化问题具有重要技术价值,尤其在面试刷题、测试数据生成和组合优化等工程场景中应用广泛。本文以C++为实践语言,深入剖析标准库`std::next_permutation`的字典序实现原理,并探讨其在处理海量数据、重复元素及与回溯法、八大排序算法结合时的应用技巧与性能调优方案。

weixin_31856057的博客 246

从Si3N4到SiNx:一文搞懂芯片制造中氮化硅的化学式玄机(附工艺参数影响)

本文深入探讨了芯片制造中氮化硅(SiNx)化学式的调控艺术,揭示了从Si3N4到SiNx的转变如何影响材料性能。通过分析PECVD和PVD工艺参数对x值的精确调控,以及x值对电学和机械性能的影响,为半导体制造提供了实用的工艺优化策略。

weixin_30776273的博客 193

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 241

BIDS数据存储格式介绍与dcm2bids安装与使用

BIDS格式&dcm2bids安装与使用

machinelearning_er的博客 7317

ERA5获取的风场数据转换为.dfs2文件

ERA5获取风场数据的具体步骤可以参考下面的文章下载好后应该是.nc格式的文件,想要读取或者转换成其他格式的文件可以安装下面步骤,本文介绍如何转换为.dfs2文件。

我的博客 1459

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 391

大语言模型应用指南:幻觉和偏见问题

大语言模型应用指南:幻觉和偏见问题 1. 背景介绍 1.1 大语言模型的发展历程 1.1.1 早期的语言模型 1.1.2 Tr

AI天才研究院 958

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 339

Ubuntu 22.04+/WSL2 中解决 `error: externally-managed-environment` 并成功安装 PyTorch + vLLM 的完整指南

Ubuntu 22.04+/WSL2 因遵循 PEP 668 规范,系统 Python 被标记为“外部管理”,导致直接使用 pip install 安装包时报错 externally-managed-environment。解决方案是创建虚拟环境: 通过 python3 -m venv ~/vllm-env 创建隔离环境 激活环境后安装 PyTorch(CUDA 12.1)和 vLLM 避免使用 sudo pip 或 --break-system-packages,防止破坏系统依赖 关键点: 虚拟环

刘一说的IT专栏 296

第三篇:NVIDIA cuOpt Python API 详解:LP、QP、MILP 建模与求解,附核心术语名词解释

NVIDIA cuOpt是一款GPU加速的优化求解库,支持LP、QP、MILP和路径优化问题。本文详细介绍了其Python API使用方法,包括核心类Problem的变量定义、约束添加、目标设置和求解配置,并提供了术语解释。cuOpt通过GPU并行计算大幅提升大规模优化问题的求解效率,支持多种求解算法和参数配置,适用于需要高性能计算的优化场景。安装方式包含pip和Docker两种,验证安装后即可快速开始建模求解。

算法工程师 236

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 70

华为HCIE之TS部分整理

TroubleShooting 整体拓扑 1. MSTP 题目需求:site1 中,CLIENT1 属于 VLAN12,CLIENT3 属于 VLAN34;MSTP 中的 VLAN12 属于 instance1,vlan34 属于 instance2;两个 instance 的主备根桥分别在 SW1 和 SW2 上,并且要求 CLIENT1访问 R1 时经过的路径是 SW3-SW1-R1;同时要求 CLIENT3 访问 R1 时经过的路径是SW3-SW2-R1; 排错思路: ①查看SW3 SW1 SW

ledrsnet的博客 5756

【C语言】字符与字符串函数

C语言中字符串为以\0结尾的字符数组,标准库函数基于此约定。本文解析字符串内存布局,详解ctype.h与string.h中字符分类、长度计算、拷贝、比较等函数的使用要点,强调长度判断与越界风险,最后通过命令行待办事项示例整合fgets、sscanf、strncpy、strcmp,展示实际应用中的关键细节。

记录在学习过程中学到的知识 347

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 304

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 437

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 211

C 语言 malloc() 详解与实战 Demo

本文详解C语言malloc()函数,涵盖其语法、内存原理及实战应用。通过动态整数、数组、结构体与链表的Demo,演示如何安全申请、使用与释放内存,强调避免内存泄漏与空指针检查的重要性,帮助开发者掌握动态内存管理核心技能。

tangPHP的博客 371

【C++ 基础入门】类和对象(上):封装、对象模型与 this 指针

C++类与对象知识(面向过程和面向对象的初步认识,类的初步认识,类的访问限定符及封装,类的作用域、实例化,类的对象模型,this指针)

2601_96587588的博客 884

蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级 备考:莫队算法离线区间查询详解

备赛进行时:第十八届蓝桥杯软件赛报名已于 2026-10-08 10:00 开启、12-18 14:00 截止,省赛定在 2027-04-10(C/C++·Python 程序设计 9:00–13:00);中国电子学会 2026 年 12 月软件编程(C/C++ 一级至十级、Python 一级至六级)考级报名 9/23–12/2 16:00、统考 12-12;全国青少年信息素养大赛 2026—2027 赛季算法应用主题赛也已进入复盘练兵窗口。

IT_Scratch的博客 137

【C++ 基础入门】C++继承(下):问题、底层原理与组合

C++继承(菱形继承的问题、虚继承原理、继承与组合、构造顺序)

2601_96587588的博客 789

C++09_vector类复习

本文以10个核心问题为主线,系统解析C++ vector的底层机制:从基本概念、初始化方式、遍历方法,到size与capacity的区别、扩容策略(VS 1.5×,g++ 2×)、reserve与resize差异、中间增删的挪动原理、迭代器失效原因,直至二维vector的内存布局(含三指针结构)。通过“先会用、再懂扩容、最后看清对象结构”的递进逻辑,揭示vector作为动态数组的本质——连续内存、自动扩容、随机访问高效,但插入删除代价高,迭代器易失效。全文深入浅出,助读者摆脱“黑盒”认知,真正掌握其内存图景

lemo_n_的博客 337

825 mW 顶上 212 °C:ASM491S 的 105 °C/W、250 mA 短路电流与热关断

25 °C 环境里结温 34.1 °C,125 °C 环境里结温 134.1 °C——后者已经离 150 °C 只有 16 °C 了,但还在范围内。换个角度看同一件事:从 25 °C 和从 125 °C 起算,温升都是 86.6 °C,但一个到 111.6 °C(还在范围内),一个到 211.6 °C(远远超限)。这个算例里 20 °C/W 是我假设的,实际值取决于机壳材料、密封程度、有没有风扇,跨度可以从 5 °C/W 到 50 °C/W 以上。外面 50 °C 的机箱,盒内就是 63.9 °C。

ANSILIC的博客 342

《C++ 项目:手写大模型接入 SDK》Gemini接口设计(上):初始化、全量响应实现和测试

本文系统完成了Gemini模型通过OpenAI兼容API的接入开发,基于Apifox验证接口规范,设计并实现GeminiProvider类,涵盖初始化、状态检测、全量响应等核心功能。重点处理了代理配置强制校验、Bearer鉴权、JSON序列化与响应解析等工程细节,并通过GTest与CMake完成单元测试,验证链路可用性。项目遵循策略模式,保持与DeepSeek、ChatGPT等模型的统一抽象接口,显著提升SDK可扩展性。

2501_91275995的博客 390

头歌 数据结构——C&C++线性表实训

本系列任务围绕线性表的链式实现,依次完成顺序构建、逆序构建、排序插入、查找、删除、求长度及栈、队列、集合等应用。通过动态内存分配与指针操作,掌握单链表的基本操作与实际应用,涵盖插入、删除、遍历、搜索等核心功能,最终实现数据结构在典型场景中的灵活运用。

一名敲代码的苦13程序员 238

字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)

本题核心思想是:最少移动步数 = 总长度 - 可保留的最长连续子串长度。未移动字母在T中必须为连续子串,在S中需保持相对顺序(即子序列)。通过枚举T的所有连续子串起点,贪心匹配S中的对应字符,求出最长可保留长度L,答案即为n−L。时间复杂度O(n²),空间复杂度O(n),适用于n≤1000。

冻柠茶飞冰走茶 587
上一篇: C++ STL之容器选型圣经
下一篇: C++ STL 之 latch / barrier / semaphore 详解(C++20 并发新原语)
Ricky_Theseus
博客等级 码龄3年 126粉丝 158原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ricky_Theseus

感谢大家,祝您生活愉快

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值