C++ STL及Python中等效实现


一. STL 概述

STL 包含以下核心组件:

  • 容器(Containers):存储数据的结构,如数组、链表、集合等。
  • 迭代器(Iterators):用于遍历容器的接口,类似指针。
  • 算法(Algorithms):通用的算法,如排序、查找、遍历等。
  • 函数对象(Functors):可调用的对象,用于自定义算法行为。
  • 适配器(Adapters):修改容器或算法行为的工具。
  • 分配器(Allocators):管理内存(竞赛中很少自定义)。

竞赛中最常用的是容器、迭代器和算法。


二. C++ STL 主要容器及 Python 对应

(1) vector(动态数组)

  • C++ vector

    • 动态大小的数组,支持随机访问,尾部增删效率高。
    • 头文件:#include <vector>
    • 常用操作:
      #include <vector>
      using namespace std;
      vector<int> v;            // 声明空向量
      v.push_back(1);           // 尾部添加元素 O(1) 均摊
      v.pop_back();             // 尾部删除 O(1)
      v.size();                 // 返回大小
      v[0];                     // 随机访问 O(1)
      v.clear();                // 清空
      v.insert(v.begin()+i, x); // 在第i位插入x O(n)
      v.erase(v.begin()+i);     // 删除第i位 O(n)
      
    • 迭代器:
      for (auto it = v.begin(); it != v.end(); ++it) {cout << *it << " ";
      }
      // 或用范围for循环(C++11)
      for (int x : v) {cout << x << " ";
      }
      
    • 竞赛技巧:
      • 初始化:vector<int> v(n, 0); 创建大小为n,元素全为0的向量。
      • 避免频繁插入/删除中间元素,复杂度为O(n)。
      • reserve(n)预分配空间,减少扩容开销。
  • Python 等效:列表(list

    • Python 的 list 是动态数组,功能与 vector 类似。
    • 常用操作:
      v = []             # 空列表
      v.append(1)        # 尾部添加 O(1) 均摊
      v.pop()            # 尾部删除 O(1)
      len(v)             # 返回大小
      v[0]               # 随机访问 O(1)
      v.clear()          # 清空
      v.insert(i, x)     # 在第i位插入x O(n)
      v.pop(i)           # 删除第i位 O(n)
      
    • 遍历:
      for x in v:print(x)
      # 或用索引
      for i in range(len(v)):print(v[i])
      
    • 差异:
      • Python 列表是内置类型,无需导入。
      • Python 列表支持更多动态类型(如混合存储 intstr),但性能比 C++ vector 低。
      • Python 无需手动管理内存扩容,但底层仍类似 vector 的动态数组。

(2) array(固定大小数组,C++11)

  • C++ array

    • 固定大小的数组,替代原生数组,接口更安全。
    • 头文件:#include <array>
    • 常用操作:
      #include <array>
      array<int, 5> arr = {1, 2, 3, 4, 5}; // 固定大小5
      arr[0];           // 随机访问 O(1)
      arr.size();       // 返回大小
      arr.fill(0);      // 填充为0
      
    • 竞赛中较少用,因 vector 更灵活。
  • Python 等效array.array 或元组(tuple

    • array.array:固定类型的数组,效率高于 list
      from array import array
      arr = array('i', [1, 2, 3])  # 'i'表示整数
      arr[0]                       # 访问
      len(arr)                     # 大小
      
    • 元组:不可变,类似固定数组。
      t = (1, 2, 3)
      t[0]  # 访问 O(1)
      
    • 差异:
      • Python 的 array.array 使用场景较窄,list 更常用。
      • 元组不可变,适合常量数据。

(3) deque(双端队列)

  • C++ deque

    • 支持两端高效增删,随机访问。
    • 头文件:#include <deque>
    • 常用操作:
      #include <deque>
      deque<int> dq;
      dq.push_back(1);      // 尾部添加 O(1)
      dq.push_front(0);     // 头部添加 O(1)
      dq.pop_back();        // 尾部删除 O(1)
      dq.pop_front();       // 头部删除 O(1)
      dq[0];                // 随机访问 O(1)
      
    • 竞赛场景:需要双端操作(如滑动窗口)。
  • Python 等效collections.deque

    • 专为双端操作设计,性能优于 list
    • 常用操作:
      from collections import deque
      dq = deque()
      dq.append(1)          # 尾部添加 O(1)
      dq.appendleft(0)      # 头部添加 O(1)
      dq.pop()              # 尾部删除 O(1)
      dq.popleft()          # 头部删除 O(1)
      dq[0]                 # 随机访问 O(1)
      
    • 差异:
      • Python 的 deque 是算法竞赛神器,尤其在需要高效双端操作时。
      • C++ deque 内存不连续,随机访问略慢于 vector

(4) list(双向链表)

  • C++ list

    • 双向链表,支持高效插入/删除,但无随机访问。
    • 头文件:#include <list>
    • 常用操作:
      #include <list>
      list<int> lst;
      lst.push_back(1);     // 尾部添加 O(1)
      lst.push_front(0);    // 头部添加 O(1)
      lst.insert(++lst.begin(), 2); // 插入 O(1)
      lst.erase(lst.begin());       // 删除 O(1)
      
    • 竞赛中较少用,因 vectordeque 更灵活。
  • Python 等效:无直接内置链表

    • Python 没有内置双向链表,list 是动态数组。
    • 可用 collections.deque 模拟链表操作,但性能不同。
    • 自定义链表:
      class ListNode:def __init__(self, val=0):self.val = valself.next = Noneself.prev = None
      
    • 差异:
      • Python 竞赛中很少用链表,因 dequelist 足以应对大多数场景。

(5) stack(栈)

  • C++ stack

    • 后进先出(LIFO)。
    • 头文件:#include <stack>
    • 常用操作:
      #include <stack>
      stack<int> s;
      s.push(1);    // 入栈 O(1)
      s.top();      // 访问栈顶 O(1)
      s.pop();      // 出栈 O(1)
      s.empty();    // 是否为空
      
    • 竞赛场景:括号匹配、单调栈。
  • Python 等效:列表(list)模拟栈

    • 无内置栈,用 list 实现:
      s = []
      s.append(1)   # 入栈 O(1)
      s[-1]         # 访问栈顶 O(1)
      s.pop()       # 出栈 O(1)
      not s         # 是否为空
      
    • 差异:
      • Python 无专用栈类型,list 足够高效。
      • 注意不要用 list 头部操作模拟栈(insert(0) O ( n ) O(n) O(n))。

(6) queue(队列)

  • C++ queue

    • 先进先出(FIFO)。
    • 头文件:#include <queue>
    • 常用操作:
      #include <queue>
      queue<int> q;
      q.push(1);    // 入队 O(1)
      q.front();    // 访问队首 O(1)
      q.pop();      // 出队 O(1)
      q.empty();    // 是否为空
      
    • 竞赛场景:BFS。
  • Python 等效collections.deque

    • deque 实现队列:
      from collections import deque
      q = deque()
      q.append(1)   # 入队 O(1)
      q[0]          # 访问队首 O(1)
      q.popleft()   # 出队 O(1)
      not q         # 是否为空
      
    • 差异:
      • Python 的 queue.Queue 适用于多线程,竞赛中用 deque 更高效。

(7) priority_queue(优先队列/堆)

  • C++ priority_queue

    • 默认大顶堆(最大值优先)。
    • 头文件:#include <queue>
    • 常用操作:
      #include <queue>
      priority_queue<int> pq;             // 大顶堆
      priority_queue<int, vector<int>, greater<int>> pq_min; // 小顶堆
      pq.push(1);    // 插入 O(log n)
      pq.top();      // 访问堆顶 O(1)
      pq.pop();      // 删除堆顶 O(log n)
      
    • 竞赛场景:贪心、Dijkstra、最小/最大k个数。
  • Python 等效heapq

    • 默认小顶堆。
    • 常用操作:
      import heapq
      pq = []
      heapq.heappush(pq, 1)    # 插入 O(log n)
      pq[0]                    # 访问堆顶 O(1)
      heapq.heappop(pq)        # 删除堆顶 O(log n)
      # 大顶堆:存负值
      pq_max = []
      heapq.heappush(pq_max, -1)
      -pq_max[0]               # 最大值
      
    • 差异:
      • Python 的 heapq 是函数接口,需用列表存储堆。
      • C++ 的 priority_queue 更简洁,支持自定义比较器。

(8) set(集合)

  • C++ set

    • 有序集合(默认升序),元素唯一,基于红黑树。
    • 头文件:#include <set>
    • 常用操作:
      #include <set>
      set<int> s;
      s.insert(1);      // 插入 O(log n)
      s.erase(1);       // 删除 O(log n)
      s.count(1);       // 查找是否存在 O(log n)
      s.lower_bound(x); // 第一个>=x的迭代器
      
    • multiset:允许重复元素。
    • 竞赛场景:去重、查找、区间查询。
  • Python 等效set

    • 无序集合,基于哈希表。
    • 常用操作:
      s = set()
      s.add(1)          # 插入 O(1) 平均
      s.remove(1)       # 删除 O(1) 平均
      1 in s            # 查找 O(1) 平均
      
    • 有序集合:sortedcontainers.SortedSet(需安装)。
    • 差异:
      • Python set 是哈希表,查找更快,但无序。
      • C++ set 是红黑树,支持有序操作(如 lower_bound)。

(9) map(映射/字典)

  • C++ map

    • 有序键值对,键唯一,基于红黑树。
    • 头文件:#include <map>
    • 常用操作:
      #include <map>
      map<string, int> m;
      m["key"] = 1;     // 插入/更新 O(log n)
      m.erase("key");   // 删除 O(log n)
      m["key"];         // 访问 O(log n)
      m.count("key");   // 查找键是否存在
      
    • multimap:允许重复键。
  • Python 等效:字典(dict

    • 基于哈希表。
    • 常用操作:
      m = {}
      m["key"] = 1      # 插入/更新 O(1) 平均
      m.pop("key")      # 删除 O(1) 平均
      m["key"]          # 访问 O(1) 平均
      "key" in m        # 查找 O(1) 平均
      
    • 有序字典:collections.OrderedDict(Python 3.7+ dict 默认有序)。
    • 差异:
      • Python dict 更快,但无红黑树支持的有序操作。
      • C++ map 适合需要键有序的场景。

(10) unordered_set/unordered_map(哈希集合/哈希表)

  • C++ unordered_set/unordered_map

    • 无序,基于哈希表,查找/插入平均 O ( 1 ) O(1) O(1)
    • 头文件:#include <unordered_set>#include <unordered_map>
    • 操作类似 set/map,但更快且无序。
    • 竞赛场景:需要极快查找/去重。
  • Python 等效set/dict

    • Python 的 setdict 就是哈希表实现。
    • 无需额外模块,性能接近 C++ 的 unordered_ 容器。

三. STL 算法及 Python 对应

STL 提供了丰富的算法,头文件为 #include <algorithm>。Python 的内置函数和模块(如 itertoolsfunctools)提供了类似功能。

(1) 排序

  • C++

    #include <algorithm>
    vector<int> v = {3, 1, 4};
    sort(v.begin(), v.end());              // 升序
    sort(v.begin(), v.end(), greater<int>()); // 降序
    // 自定义比较
    sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
    
    • 复杂度: O ( n l o g n ) O(n log n) O(nlogn)
  • Python

    v = [3, 1, 4]
    v.sort()                     # 升序
    v.sort(reverse=True)         # 降序
    # 自定义比较
    v.sort(key=lambda x: -x)
    # 或用 sorted() 返回新列表
    sorted_v = sorted(v)
    
    • Python 的 sort 是 Timsort,性能优秀。

(2) 二分查找

  • C++

    vector<int> v = {1, 2, 3, 4};
    // 要求 v 已排序
    binary_search(v.begin(), v.end(), 3); // 是否存在
    lower_bound(v.begin(), v.end(), 3);   // 第一个>=3
    upper_bound(v.begin(), v.end(), 3);   // 第一个>3
    
    • 复杂度: O ( l o g n ) O(log n) O(logn)
  • Python

    from bisect import bisect_left, bisect_right
    v = [1, 2, 3, 4]
    3 in v                     # 是否存在 O(n),竞赛慎用
    bisect_left(v, 3)          # 第一个>=3
    bisect_right(v, 3)         # 第一个>3
    
    • Python 的 bisect 模块专为二分查找设计。

(3) 最大/最小值

  • C++

    vector<int> v = {3, 1, 4};
    *max_element(v.begin(), v.end()); // 最大值
    *min_element(v.begin(), v.end()); // 最小值
    
  • Python

    v = [3, 1, 4]
    max(v)    # 最大值
    min(v)    # 最小值
    

(4) 其他算法

  • C++
    • reverse(v.begin(), v.end()):反转。
    • unique(v.begin(), v.end()):去重(需先排序)。
    • next_permutation(v.begin(), v.end()):下一个排列。
  • Python
    • v.reverse()v[::-1]:反转。
    • list(set(v)):去重(无序)。
    • itertools.permutations:生成排列。

四. 竞赛中的注意事项

C++ STL

  • 性能:选择合适的容器(如 vector 快于 listunordered_set 快于 set)。
  • 边界检查:访问 vector 前检查 empty(),避免越界。
  • 自定义比较:优先队列和 sort 的比较器要严格弱序(避免 a == b 时不一致)。
  • 内存管理:大数据量时用 reserveswap 清空容器。
  • 调试:用 cerr 输出容器内容,便于调试。

Python

  • 性能:避免频繁用 in 检查列表( O ( n ) O(n) O(n)),改用 set O ( 1 ) O(1) O(1))。
  • 模块:熟悉 collectionsdequeCounter)、heapqbisect
  • 简洁性:Python 代码短,但运行时常数大,注意 TLE(超时)。
  • 输入输出:用 sys.stdin.readline 加速大输入。

五. 示例:解决一个竞赛问题

问题:给定一个数组,找出所有和为目标值的子数组(不要求连续)。

  • C++ 解法(用 map 记录前缀和):

    #include <iostream>
    #include <vector>
    #include <map>
    using namespace std;
    long long countSubarrays(vector<int>& nums, int target) {map<long long, int> prefixSum;prefixSum[0] = 1;long long sum = 0, count = 0;for (int num : nums) {sum += num;count += prefixSum[sum - target];prefixSum[sum]++;}return count;
    }
    int main() {vector<int> nums = {1, 2, 3, -3, 3};cout << countSubarrays(nums, 3) << endl; // 输出 4return 0;
    }
    
  • Python 解法(用 dict):

    from collections import defaultdict
    def count_subarrays(nums, target):prefix_sum = defaultdict(int)prefix_sum[0] = 1sum_ = 0count = 0for num in nums:sum_ += numcount += prefix_sum[sum_ - target]prefix_sum[sum_] += 1return count
    nums = [1, 2, 3, -3, 3]
    print(count_subarrays(nums, 3))  # 输出 4
    

分析

  • C++ 用 map 记录前缀和,键有序但稍慢。
  • Python 用 defaultdict(哈希表),更快且代码更简洁。
  • 两者逻辑相同,Python 写法更直观,C++ 运行效率更高。

六. 总结

  • C++ STL

    • 优点:高效(编译期优化)、容器丰富(vectorsetmap 等)、算法强大(sortbinary_search)。
    • 缺点:语法复杂,需手动管理内存,调试稍麻烦。
    • 竞赛推荐:vectorpriority_queuesetmapunordered_map
  • Python 等效

    • 优点:代码简洁,内置功能强大(listsetdict),模块丰富(collectionsheapq)。
    • 缺点:运行时常数大,易超时,需优化输入输出。
    • 竞赛推荐:listdequeheapqsetdict

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python-63-前后端分离之图书管理系统的Flask后端

文章目录 1 flask后端1.1 数据库实例extension.py1.2 数据模型models.py1.3 .flaskenv1.4 app.py1.5 运行1.6 测试链接2 关键函数和文件2.1 请求视图类MethodView2.2 .flaskenv文件3 参考附录基于flask形成了图书管理系统的后端,同时对其中使用到的关键文件.flaskenv和函数类M…

蓝桥杯真题——好数、R格式

目录 蓝桥杯2024年第十五届省赛真题-好数 【模拟题】 题目描述 输入格式 输出格式 样例输入 样例输出 提示 代码1&#xff1a;有两个案例过不了&#xff0c;超时 蓝桥杯2024年第十五届省赛真题-R 格式 【vector容器的使用】 题目描述 输入格式 输出格式 样例输入…

Python中NumPy的索引和切片

在数据科学和科学计算领域&#xff0c;NumPy是一个功能强大且广泛使用的Python库。它提供了高效的多维数组对象以及丰富的数组操作函数&#xff0c;其中索引和切片是NumPy的核心功能之一。通过灵活运用索引和切片操作&#xff0c;我们可以轻松访问和操作数组中的元素&#xff0…

设计模式:策略模式 - 消除复杂条件判断的利器

一、什么是策略模式&#xff1f; 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它将一组算法或业务逻辑封装为独立的策略类&#xff0c;使这些策略可以互换使用&#xff0c;并通过上下文类动态选择合适的策略。 核心思想 • 将不同的行…

LeetCode hot 100—不同路径

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; …

pytorch查询字典、列表维度

输出tensor变量维度 print(a.shape)输出字典维度 for key, value in output_dict.items():if isinstance(value, torch.Tensor):print(f"{key} shape:", value.shape)输出列表维度 def get_list_dimensions(lst):# 基线条件&#xff1a;如果lst不是列表&#xff0…

多坐标系变换全解析:从相机到WGS-84的空间坐标系详解

多坐标系变换全解析:从相机到WGS-84的空间坐标系详解 一、常见坐标系简介二、各坐标系的功能和使用场景1. WGS-84 大地坐标系(经纬高)2. 地心直角坐标系(ECEF)3. 本地 ENU / NED 坐标系4. 平台坐标系(Body)5. 相机坐标系三、坐标变换流程图四、如何选用合适的坐标系?五…

【NumPy科学计算:高性能数组操作核心指南】

目录 前言&#xff1a;技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解关键技术模块技术选型对比 二、实战演示环境配置要求核心代码实现运行结果验证 三、性能对比测试方法论量化数据对比结果分析 四、最佳实践推荐方案 ✅常见错误 ❌调试技…

【特权FPGA】之PS/2键盘解码

0 故事背景 见过这种接口的朋友们&#xff0c;大概都已经成家立业了吧。不过今天我们不讨论这种接口的历史&#xff0c;只讲讲这种接口的设计。&#xff08;如果还没有成家的朋友也别生气&#xff0c;做自己想做的事情就对了&#xff01;&#xff09; 1 时序分析 数据帧格式如图…

DAPP实战篇:使用web3.js实现前端输入钱包地址查询该地址的USDT余额—操作篇

专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读396次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你想要知道区块…

高中生学习数据隐私保护的“技术-制度-文化”协同机制研究

一、引言 1.1 研究背景与意义 在数字化时代的浪潮下&#xff0c;教育领域正经历着深刻的变革&#xff0c;智能教育平台如雨后春笋般涌现&#xff0c;为高中教育带来了新的活力与机遇。这些平台借助先进的信息技术&#xff0c;能够实时收集、分析大量的高中生学习数据&#xf…

【Java多线程】告别线程混乱!深度解析Java多线程4大实现方式(附实战案例)

一、继承Thread类 实现步骤&#xff1a; 1.继承Thread类 2.重写run()方法 3.创建线程对象并调用start()方法 示例&#xff1a; class MyThread extends Thread {Overridepublic void run() {for (int i 0; i < 5; i) {System.out.println(Thread.currentThread().getNam…

全国产V7-690T核心板/算法验证板/FPGA开发板

UD SOM-404全国产化信号处理模块既可以作为核心板使用&#xff0c;也可以单独使用。FPGA对外有80组GTY通过两个FMC连接器全部引出&#xff0c;多个模块可以级联使用&#xff0c;扩展信号处理能力。FMC连接器也满足标准规范&#xff0c;可以插入标准的FMC或FMC子板。模块为100%国…

STM32_HAL库提高中断执行效率

目录 中断流程分析我的解决办法优缺点 大家都在说STM32 HAL 库中断效率低下。具体哪里不行&#xff1f;如何优化&#xff1f; 我手里的项目要用到多个定时器TIM6、TIM7、TIM9、TIM10、TIM11、TIM12、TIM13&#xff0c;在处理这些定时器中断的时候&#xff0c;也发现了这个问题。…

RabbitMQ惰性队列的工作原理、消息持久化机制、同步刷盘的概念、延迟插件的使用方法

惰性队列工作原理 惰性队列通过尽可能多地将消息存储到磁盘上来减少内存的使用。与传统队列相比&#xff0c;惰性队列不会主动将消息加载到内存中&#xff0c;而是尽量让消息停留在磁盘上&#xff0c;从而降低内存占用。尽管如此&#xff0c;它并不保证所有操作都是同步写入磁…

Spark Core(二)

Spark-Core编程&#xff08;二&#xff09; RDD转换算子 RDD 根据数据处理方式的不同将算子整体上分为 Value 类型、双 Value 类型和 Key-Value 类型 Value类型 1&#xff09;map 将处理的数据逐条进行映射转换&#xff0c;这里的转换可以是类型的转换&#xff0c;也可以是…

C#打开文件及目录脚本

如果每天开始工作前都要做一些准备工作&#xff0c;比如打开文件或文件夹&#xff0c;我们可以使用代码一键完成。 using System.Diagnostics; using System.IO;namespace OpenFile {internal class Program{static void Main(string[] args){Console.WriteLine("Hello, …

Python生成exe

其中的 -w 参数是 PyInstaller 用于窗口模式&#xff08;Windowed mode&#xff09;&#xff0c;它会关闭命令行窗口的输出&#xff0c;这通常用于 图形界面程序&#xff08;GUI&#xff09;&#xff0c;比如使用 PyQt6, Tkinter, PySide6 等。 所以&#xff1a; 如果你在没有…

【大模型微调】如何解决llamaFactory微调效果与vllm部署效果不一致如何解决

以下个人没整理太全 一、生成式语言模型的对话模板介绍 使用Qwen/Qwen1.5-0.5B-Chat训练 对话模板不一样。回答的内容就会不一样。 我们可以看到例如qwen模型的tokenizer_config.json文件&#xff0c;就可以看到对话模板&#xff0c;一般同系列的模型&#xff0c;模板基本都…

Linux网络编程——详解网络层IP协议、网段划分、路由

目录 一、前言 二、IP协议的认识 1、什么是IP协议&#xff1f; 2、IP协议报头 三、网段划分 1、初步认识IP与路由 2、IP地址 I、DHCP动态主机配置协议 3、IP地址的划分 I、CIDR设计 II、子网数目的计算 III、子网掩码的确定 四、特殊的IP地址 五、IP地址的数量限…