非修改序列

  1. 批量操作
    1. a
      • 序列容器
        • a
        • a
        • a
        • a
        a
        
      • 关联容器
        • a
        • a
        • a
        • a
        a
        
      • 哈希容器
        • a
        • a
        • a
        • a
        a
        
      a
      a
      
  2. 搜索
    1. std::find, std::find_if
      • 序列容器:✔,线性遍历 O(n)

        • 查找区间 [first, last)

        • 返回第一个匹配元素的迭代器

        • 若未找到,返回 last

        InputIt find(InputIt first, InputIt last, const T& value);
        
        InputIt find_if(InputIt first, InputIt last, UnaryPredicate pred);
        
      • 关联容器:✔,适合 按值查找 O(n)

        • 按键查找 用 成员函数
        auto it = find_if(container.begin(), container.end(),
            [&value](const auto& pair) {
                return pair.second == value;
            });
        
      • 哈希容器:✔,参考关联容器

    2. std::count, std::count_if
      • 序列容器:✔,线性遍历 O(n)

        • 返回匹配元素的数量
        int count( InputIt first, InputIt last, const T& value )
        
        int count_if( InputIt first, InputIt last, UnaryPredicate p );
        
      • 关联容器:✔,参考 序列容器 和 std::find 中的 关联容器

      • 哈希容器:✔,同上

修改序列

  1. 复制

  2. 交换

  3. 变换

  4. 生成

  5. 移除

    1. std::unique
      • 序列容器:✔, O(n)

        • 要求 前向迭代器

        • 只能处理相邻的重复元素

        • 将不需要移除的元素
          依次向前移动
          覆盖掉需要移除的元素

        • 返回的迭代器是
          最后一个保留元素的下一个位置

        • 需用  erase  才能
          删除从该迭代器到原尾端的元素
          否则容器大小不变

        ForwardIt unique( ForwardIt first, ForwardIt last,
                          BinaryPredicate p = equal_to<T>() );
        
        • 移除所有重复元素
          排序 + unique + erase
      • 关联容器:×

        • multimap, multiset
          参考std::remove
      • 哈希容器:×

        • unordered_multimap, unordered_multiset
          参考std::remove
    2. std::remove, std::remove_if
      • 序列容器:✔,O(n)

        • 参考 std::unique
        ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
        
        ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPred p );
        
      • 关联容器:×

        • remove 移动有效元素覆盖无效元素
          而非物理删除
          破坏有序性
      • 哈希容器:×

        • remove 移动有效元素覆盖无效元素
          而非物理删除
          破坏哈希分布
  6. 顺序更改(仅讨论序列容器)

    1. reverse, 遍历 O(n)

      • forward_list 除外

      • std::reverse 要求
        双向迭代器 或 随机访问迭代器

      • 就地修改
        第一个元素与最后一个元素交换
        第二个与倒数第二个交换

      • 反转  [first, last)

      void reverse( BidirIt first, BidirIt last );
      
      reverse(arr, arr + n);
      

数值

排序

  1. 划分(仅讨论序列容器)

    1. partition 和 stable_partition

      • partition:遍历 O(n)
        stable_partition:有辅助空间则 O(n),否则 O(nlogn)

      • partition:原地
        stable_partition:可能原地

      • partition:快排的划分,简单选择排序
        找到第一个不满足 p 的元素 A
        如果 A 不存在,返回 last
        如果 A 存在,用 pos 迭代器指向 A
        自 A 向后遍历剩余元素
        如果有满足 p 的元素,与 A 交换
        pos 迭代器后移

      • stable_partition:

        • 有临时容器(与原序列等长)
          第一次遍历原序列,将所有满足 p 的元素依次复制到临时容器的前端
          第二次遍历原序列,将所有不满足 p 的元素依次复制到临时容器的后端
          将临时容器的内容复制回原序列

        • 无临时容器归并排序,自顶向下)
          原序列分为前后两半
          递归地对两半分别 stable_partition,得到
          前半部分:满足 p 的 A1 + 不满足 p 的 A2
          后半部分:满足 p 的 B1 + 不满足 p 的 B2
          交换 A2 和 B1
          先反转 A2,再反转 B1,最后反转 A2 + B1 的整体
          反转 → 双向迭代器

      • partition:不保留元素的相对顺序
        stable_partition:保留元素的相对顺序

      • 重新排序 [first, last)

      • p 返回 true 的所有元素 都位于
        p 返回 false 的所有元素 之前

      • 返回的迭代器指向
        第一个不满足 p 的元素
        (第二组第一个元素)

      ForwardIt partition( ForwardIt first, ForwardIt last, UnaryPred p );
      
      BidirIt stable_partition( BidirIt first, BidirIt last, UnaryPred p );
      
    2. partition_copy,遍历 O(n)

      • 返回值:分别指向两个目标区间的 last

      • 源容器不动

      pair<OutputIt1, OutputIt2> partition_copy( InputIt first, InputIt last,
                                                OutputIt1 d_first_true, OutputIt2 d_first_false,
                                                UnaryPred p );
      
    3. is_partitioned,遍历 O(n)

      bool is_partitioned( InputIt first, InputIt last, UnaryPred p );
      
    4. partition_point

      • 前提:区间已按 p 划分

      • 随机访问迭代器:二分查找 O(logn)
        list,forward_list :遍历 O(n)

      • 返回的迭代器指向
        第一个不满足 p 的元素
        (第二组第一个元素)

      • 当谓词固定为 e < value
        且升序排序时
        partition_point 就等价于 lower_bound

      ForwardIt partition_point( ForwardIt first, ForwardIt last, UnaryPred p );
      
  2. 排序(仅讨论序列容器)

    1. sort,O(nlogn)

      • list, forward_list 除外

      • std::sort 要求 随机访问迭代器

      • 结合了

        • 快速排序

        • 排序
          快速排序递归深度超过阈值时,启用堆排序
          避免快速排序 O (n²) 退化

        • 插入排序
          子数组规模足够小

      void sort( RandomIt first, RandomIt last, 
                 Compare comp = less<T>() );
      

      原生数组通过指针作为迭代器
      也可以用 std::sort

      sort(arr, arr + n);
      
  3. 二分搜索(已划分)(仅讨论序列容器)

    1. equal_range

      • array, vector, deque, string
        随机访问迭代器
        二分查找, O(log n)

      • list, forward_list
        前向迭代器和双向迭代器
        线性扫描,O(n)

      • 必须先按比较器规则排序
        先找  lower_bound 
        再找  upper_bound

      • string:只能查找单个字符
        不能查找子串

      pair<ForwardIt, ForwardIt> equal_range( ForwardIt first, 
                                              ForwardIt last, 
                                              const T& value, 
                                              Compare comp = less<T>() );
      

      适合 已排序 + 统计个数 + 支持随机访问迭代器

      vector<int>vec2 = { 1, 4, 4, 4, 5, 6 };
      auto p = equal_range(vec2.begin(), vec2.end(), 4);
      int num2 = p.second - p.first; // 迭代器减法
      // num2 为 3
      

    2. lower_bound, upper_bound

      • 序列容器:✔,时间复杂度 参考 std::equal_range

        • 需要已排序

        • 找到:指向第一个满足 element >= value 的元素(lower_bound)

        • 找到:指向第一个满足 element > value 的元素(upper_bound)

        • 未找到:返回 last

        ForwardIt lower_bound( ForwardIt first, ForwardIt last, const T& value, 
                               Compare comp = less<T>() );
        
      • 关联容器:✔,参考 序列容器 和 std::find 中的 关联容器

      • 哈希容器:×

    3. binary_search

      • 时间复杂度 参考 std::equal_range

      • 需要已排序

      • 仅检查 是否存在 等效元素
        要获取指向该元素(如果存在)的迭代器
        应改用 std::lower_bound

      bool binary_search( ForwardIt first, ForwardIt last,
                            const T& value, Compare comp = less<T>());
      
  4. 集合(已排序)

  5. 归并(已排序)

    1. std::merge

      • 序列容器:✔
        • 除了两个链表容器外
          都没有成员函数 merge
      • 关联容器:✔
      • 哈希容器:×

      两个输入序列已按比较器规则排序
      新序列仍然保持有序
      返回新序列的 end

      都是 O(n + m)

      OutputIt merge( InputIt1 first1, InputIt1 last1,
                      InputIt2 first2, InputIt2 last2,
                      OutputIt d_first, Compare comp = less<T>() );
      
  6. 最值

  7. 字典序比较

  8. 排列

其他

  1. 不知道什么时候才有空整理

    1. std::getline 与 cin.getline

      // cin.getline()
      istream& getline(char* s, streamsize n);
      istream& getline(char* s, streamsize n, char delim);
      
      // std::getline()
      istream& getline(istream& is, string& str);
      istream& getline(istream& is, string& str, char delim);
      

      两者都默认以换行符 \n 作为分隔符
      两者都会从流中提取并丢弃分隔符

      cin.getline(): 有缓冲区溢出风险(如果提供的缓冲区太小)
      std::getline(): 无缓冲区溢出风险

    2. substr

      basic_string substr( size_type pos = 0, size_type count = npos ) const;
      

      等效于 string 的构造函数

      return basic_string(*this, pos, count);
      
    3. string::size() 和 string::length()
      完全等价

    4. substr

      basic_string substr( size_type pos = 0, size_type count = npos ) const;
      
    5. fixed 和 setprecision 和 scientific

      • 不使用 fixed 或 scientific
        setprecision(n) 保留 n 位有效数字

      • 使用 fixed
        setprecision(n) 小数点后保留 n 位

      • 使用 scientific
        setprecision(n) 科学计数法中,小数点后保留 n 位。

posted on 2025-08-26 14:55  2024211826  阅读(15)  评论(0)    收藏  举报