当前位置: 首页 > news >正文

全面解析 C++ STL 中的 set 和 map

C++ 标准模板库(STL)中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中,setmap 是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度,详细解读它们的设计与使用。


目录

1. 什么是关联式容器

关联式容器的核心特性

2. set 容器详解

2.1 基本概念与特性

2.2 底层实现:红黑树

红黑树的特性

红黑树的操作

2.3 构造函数

2.4 常用操作与复杂度分析

插入操作

查找操作

删除操作

遍历

2.5 特殊操作与技巧

(1) 自定义排序规则

(2) 范围删除

(3) 应用:求两个数组的交集

2.6 multiset 的区别与应用



1. 什么是关联式容器

关联式容器是一类根据关键字组织和管理数据的容器。与序列式容器(如 vectorlist)相比,关联式容器的主要区别如下:

特性关联式容器(set/map序列式容器(vector/list
数据存储顺序按关键字排序按插入顺序
数据访问复杂度O(log⁡N)O(\log N)O(logN)O(1)O(1)O(1) 或 O(N)O(N)O(N)
是否支持随机访问
是否支持按索引访问

关联式容器分为有序和无序两类:

  1. 有序容器:如 setmap,基于平衡二叉树(红黑树)实现,数据按排序规则组织。
  2. 无序容器:如 unordered_setunordered_map,基于哈希表实现,提供更高效的查找速度,但不保证元素顺序。

关联式容器的核心特性

  • 键值对:关联式容器通过关键字对元素进行组织,set 中的关键字即为数据本身,而 map 则以键值对形式存储数据。
  • 自动排序:有序容器会自动对数据进行排序(升序或自定义规则)。
  • 高效操作:插入、删除、查找的平均时间复杂度为 O(log⁡N)O(\log N)O(logN)(红黑树实现)。

2. set 容器详解

2.1 基本概念与特性

set 是一种集合数据结构,用于存储唯一且自动排序的元素。它的主要特点如下:

  • 数据唯一性:同一元素不能重复插入。
  • 自动排序:默认按升序排序,可通过自定义比较器更改排序规则。
  • 迭代器类型set 支持双向迭代器,不支持随机访问。
  • 底层实现:使用红黑树作为存储结构。

2.2 底层实现:红黑树

红黑树的特性

红黑树是一种平衡二叉搜索树,满足以下性质:

  1. 每个节点是红色或黑色。
  2. 根节点是黑色。
  3. 每个叶子节点(nullptr 或 NIL 节点)是黑色。
  4. 如果一个节点是红色,则其子节点必须是黑色(即红色节点不能相邻)。
  5. 从任意节点到其每个叶子节点的路径都包含相同数量的黑色节点。
红黑树的操作
  • 插入:通过旋转和重新着色,确保平衡性和红黑性质。
  • 删除:比插入更复杂,同样通过旋转和着色维护树的性质。
  • 查找:沿树遍历,时间复杂度为 O(log⁡N)O(\log N)O(logN)。

setmap 中,红黑树用来高效实现元素的有序存储和快速查找。


2.3 构造函数

set 提供以下几种构造方式:

  1. 默认构造:创建一个空集合。
    set<int> s;
    
  2. 初始化列表构造:直接用 {} 初始化集合。
    set<int> s = {3, 1, 4, 1, 5, 9};  // 重复元素自动去重
    
  3. 迭代器区间构造:从其他容器的元素构造集合。
    vector<int> v = {1, 2, 3, 4};
    set<int> s(v.begin(), v.end());
    
  4. 自定义比较规则
    set<int, greater<int>> s = {3, 1, 4};  // 按降序排序
    


2.4 常用操作与复杂度分析

操作函数复杂度说明
插入insert(value)O(log⁡N)O(\log N)O(logN)插入元素,若已存在则插入失败
删除erase(value)O(log⁡N)O(\log N)O(logN)删除指定元素
查找find(value)O(log⁡N)O(\log N)O(logN)返回迭代器,指向目标元素
统计count(value)O(log⁡N)O(\log N)O(logN)判断元素是否存在,结果为 0 或 1
遍历begin(), end()O(N)O(N)O(N)正向迭代访问所有元素
下界/上界lower_bound()/upper_bound()O(log⁡N)O(\log N)O(logN)返回 >= / > 某值的第一个元素的迭代器
插入操作
set<int> s;
auto res = s.insert(10);  // 插入 10
if (res.second) {cout << "插入成功" << endl;
} else {cout << "插入失败" << endl;
}
查找操作
if (s.find(20) != s.end()) {cout << "找到元素 20" << endl;
}
删除操作
s.erase(10);  // 删除值为 10 的元素
遍历
for (int x : s) {cout << x << " ";  // 正向遍历
}
for (auto it = s.rbegin(); it != s.rend(); ++it) {cout << *it << " ";  // 反向遍历
}

2.5 特殊操作与技巧

(1) 自定义排序规则

set 默认按升序排序,使用仿函数或 std::greater 可修改排序规则:

set<int, greater<int>> s = {3, 1, 4};
(2) 范围删除

删除值在 [low, high) 范围内的所有元素:

s.erase(s.lower_bound(10), s.upper_bound(50));
(3) 应用:求两个数组的交集
vector<int> intersection(const vector<int>& nums1, const vector<int>& nums2) {set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());vector<int> result;for (int x : s1) {if (s2.count(x)) result.push_back(x);}return result;
}

2.6 multiset 的区别与应用

multisetset 的区别在于:

  1. multiset 允许存储重复元素。
  2. 插入、删除和查找操作的接口与 set 相同,但返回的结果会包含重复项。
multiset<int> ms = {1, 2, 2, 3};
ms.insert(2);  // 再次插入 2

3. map 容器详解

3.1 基本概念与特性

map 是一个关联式容器,用于存储键值对(key-value)。与 set 相比,map 不仅存储键(key),还存储与每个键关联的值(value)。
map 的主要特点包括:

  • 键唯一性:每个键在 map 中都是唯一的。
  • 自动排序:默认按照键的升序排序,也可以通过自定义比较器来更改排序规则。
  • 底层实现:基于红黑树实现,操作复杂度为 O(log⁡N)O(\log N)O(logN)。
  • 支持随机访问:与 set 不同,map 中存储的键值对支持通过键快速查找对应的值。
map<int, string> m;
m[1] = "apple";  // 插入键值对 (1, "apple")
m[2] = "banana"; // 插入键值对 (2, "banana")
m[3] = "cherry"; // 插入键值对 (3, "cherry")
内部存储结构

map 使用红黑树存储数据,保证了所有元素按键值自动排序。在 map 中,每个节点存储一个 pair<const Key, T>,其中 const Key 表示键,T 表示值。红黑树的特点确保了查找、插入和删除操作的时间复杂度都为 O(log⁡N)O(\log N)O(logN)。


3.2 构造与初始化

map 提供了多种构造方法,以适应不同的使用场景:

  1. 默认构造:创建一个空 map

    map<int, string> m;
    
  2. 初始化列表构造:通过初始化列表直接创建 map

    map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
    
  3. 范围构造:从另一个容器(如 setvector 等)构造 map

    vector<pair<int, string>> v = {{1, "apple"}, {2, "banana"}};
    map<int, string> m(v.begin(), v.end());
    
  4. 自定义比较器:通过传入自定义比较器,指定键的排序方式。

    map<int, string, greater<int>> m;  // 降序排序
    m[2] = "banana";
    m[1] = "apple";
    

3.3 常用操作与复杂度分析

操作函数复杂度说明
插入insert(pair)O(log⁡N)O(\log N)O(logN)插入一个键值对,若已存在则插入失败
插入或修改operator[]O(log⁡N)O(\log N)O(logN)插入新元素或修改已有元素的值
查找find(key)O(log⁡N)O(\log N)O(logN)查找指定键,返回键值对的迭代器
统计count(key)O(log⁡N)O(\log N)O(logN)查找指定键是否存在(map 中为 0 或 1)
删除erase(key)O(log⁡N)O(\log N)O(logN)删除指定键及其对应的值
遍历begin(), end()O(N)O(N)O(N)正向遍历所有元素
下界/上界lower_bound(key)/upper_bound(key)O(log⁡N)O(\log N)O(logN)查找大于等于某值或大于某值的第一个元素
插入与查找操作
  • 插入:可以通过 insert 方法插入新的键值对,也可以通过 operator[] 插入或修改键值对。

    map<int, string> m;
    m.insert({1, "apple"});
    m[2] = "banana";  // 插入或修改
    
  • 查找:find 方法返回一个迭代器,指向指定键的键值对,若未找到则返回 end()

    auto it = m.find(1);
    if (it != m.end()) {cout << "Found: " << it->second << endl;  // 输出 "apple"
    }
    

删除操作

删除某个键值对:

m.erase(1);  // 删除键为 1 的元素

3.4 遍历与修改

map 提供了多种遍历方法:

  1. 范围 for

    for (const auto& [key, value] : m) {cout << key << ": " << value << endl;
    }
    
  2. 传统迭代器

    for (auto it = m.begin(); it != m.end(); ++it) {cout << it->first << ": " << it->second << endl;
    }
    
修改值

可以通过迭代器直接修改值,operator[] 也支持修改已有键的值:

m[2] = "grape";  // 修改键为 2 的值为 "grape"
auto it = m.find(2);
if (it != m.end()) {it->second = "orange";  // 通过迭代器修改值
}

3.5 特殊操作与进阶技巧

(1) 下界与上界

通过 lower_bound()upper_bound() 方法,可以获取某个键的下界和上界,常用于区间查找。

  • lower_bound(key):返回第一个大于等于 key 的元素。
  • upper_bound(key):返回第一个大于 key 的元素。
map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
auto lb = m.lower_bound(2);  // 返回键为 2 或大于 2 的第一个元素
cout << lb->second << endl;  // 输出 "banana"
(2) 自定义排序规则

如同 setmap 也可以通过自定义比较器来实现不同的排序规则。

map<int, string, greater<int>> m = {{1, "apple"}, {3, "cherry"}, {2, "banana"}};
for (const auto& [key, value] : m) {cout << key << ": " << value << endl;
}  // 输出:3: cherry 2: banana 1: apple
(3) 范围删除

删除某个键值范围内的元素,常用于清除一段区间:

map<int, string> m = {{1, "apple"}, {2, "banana"}, {3, "cherry"}};
m.erase(m.lower_bound(2), m.upper_bound(3));  // 删除键为 2 和 3 的元素

3.6 multimap 的区别与应用

multimapmap 的扩展,允许相同的键有多个值(即支持键的冗余)。与 map 的区别在于,multimap 在插入重复键时不会丢失数据,而 map 会自动覆盖原有键。

multimap<int, string> mm;
mm.insert({1, "apple"});
mm.insert({1, "banana"});
mm.insert({2, "cherry"});for (const auto& [key, value] : mm) {cout << key << ": " << value << endl;  // 输出:1: apple 1: banana 2: cherry
}

multimap 在某些场景下非常有用,例如存储学生成绩时,可能有多个学生取得相同的分数。


4. 高级案例:综合利用 setmap

4.1 查找两个数组的交集

vector<int> intersection(const vector<int>& nums1, const vector<int>& nums2) {set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());vector<int> result;for (int x : s1) {if (s2.count(x)) result.push_back(x);}return result;
}

4.2 构建词频统计表

map<string, int> wordCount(const vector<string>& words) {map<string, int> wordMap;for (const string& word : words) {wordMap[word]++;}return wordMap;
}

4.3 高效查找链表中的环

bool hasCycle(ListNode* head) {set<ListNode*> visited;while (head != nullptr) {if (visited.find(head) != visited.end()) {return true;  // 找到环}visited.insert(head);head = head->next;}return false;
}

5. 性能优化与注意事项

5.1 使用 unordered_mapunordered_set

在很多查找密集型的应用中,unordered_mapunordered_set 基于哈希表实现,提供常数时间复杂度 O(1)O(1)O(1) 的查找和插入操作。它们的性能优势适用于不需要保持元素顺序的场景。

5.2 避免不必要的拷贝

当插入大量数据时,可以使用 emplace() 来避免不必要的对象拷贝。emplace() 可以直接构造元素,而无需创建临时对象。

map<int, string> m;
m.emplace(1, "apple");  // 不会发生拷贝

5.3 避免频繁修改键

map 不支持修改键,修改键会导致数据结构破坏。因此,避免频繁修改键,而应使用新的键值对进行插入和删除。


6. 总结

通过本文的详细解析,我们全面了解了 C++ 中 setmap 容器的使用、底层实现以及高效操作技巧。掌握这些基本知识后,开发者可以灵活使用 setmap 来处理各种复杂的关联数据问题,从而提高程序的效率和可读性。

在实际开发中,选择合适的容器(如 mapunordered_mapsetunordered_set)可以帮助我们应对不同的数据处理需求,避免性能瓶颈。希望通过本文的学习,你能够深入掌握这些强大的容器,提升 C++ 编程技能。

相关文章:

全面解析 C++ STL 中的 set 和 map

C 标准模板库&#xff08;STL&#xff09;中的关联式容器以其强大的功能和高效性成为开发者解决复杂数据组织问题的重要工具。其中&#xff0c;set 和 map 是最常用的两类关联容器。本篇博客将从基本特性、底层实现、用法详解、高级案例以及性能优化等多个角度&#xff0c;详细…...

css:怎么设置div背景图的透明度为0.6不影响内部元素

目录 1.前言 2.解决思路 3.具体实例 4.另外一种实例 5.总结 1.前言 div背景图为project-bg.png&#xff0c;设置div透明度为0.6&#xff1b;div内的名称、数值受透明度影响颜色显示不正常&#xff1b;怎么设置背景图的透明度为0.6不影响内部元素&#xff1b; 2.解决思路 …...

Kubernetes ConfigMaps

文章目录 简介创建ConfigMaps通过命令行使用字面值创建 ConfigMap。从文件创建ConfigMaps从多个文件创建 ConfigMap从目录创建 ConfigMap使用 YAML 创建 ConfigMap 使用ConfigMaps使用 ConfigMaps作为环境变量使用 ConfigMap 作为卷挂载使用 ConfigMap 中的特定的key ConfigMap…...

前端热门面试题目[一](HTML、CSS、Javascript、Node、Vue、React)

如何设计一个前端页面&#xff0c;实现PC端访问展示Web应用&#xff0c;移动端访问展示H5应用&#xff1f; 为了实现这一功能&#xff0c;通常需要使用响应式设计或者服务器端检测用户设备并返回相应的页面。以下是一些实现方法&#xff1a; 响应式设计&#xff1a;通过CSS媒…...

Swift 宏(Macro)入门趣谈(五)

概述 苹果在去年 WWDC 23 中就为 Swift 语言新增了“其利断金”的重要小伙伴 Swift 宏&#xff08;Swift Macro&#xff09;。为此&#xff0c;苹果特地用 2 段视频&#xff08;入门和进阶&#xff09;颇为隆重的介绍了它。 那么到底 Swift 宏是什么&#xff1f;有什么用&…...

ES6 Set、Map、WeakSet、WeakMap 四者辨析与实战应用详解

在 ES6 中,Set 和 Map 是两种非常重要的新增数据结构,它们都具有独特的特性和用途,能够帮助开发者更高效地处理和管理数据。除此之外,WeakSet 和 WeakMap 作为这两种数据结构的变种,也具有一些特殊的功能。下面我会从 Set 数据结构、Map 数据结构、WeakSet 和 WeakMap 对比…...

【数据结构】哈希表实现

前言 在本篇博客中&#xff0c;作者将会带领你使用C语言来实现一个哈希表。 一.什么是哈希表 在实现哈希表之前&#xff0c;我们先来学习一下什么是哈希表。 在传统的数据结构中&#xff0c;例如数组&#xff0c;链表和二叉平衡树等数据结构&#xff0c;这些数据结构的元素关键…...

Verilog的线与类型与实例化模块

1、线与类型 在Verilog中&#xff0c;线与&#xff08;wire-AND&#xff09;类型通常用于描述多个信号进行逻辑与&#xff08;AND&#xff09;操作的电路行为。虽然Verilog本身没有直接定义一种名为“线与”的数据类型&#xff0c;但可以通过使用wire类型结合特定的逻辑操作来…...

芯片测试-RF中的S参数,return loss, VSWR,反射系数,插入损耗,隔离度等

RF中的S参数&#xff0c;return loss, VSWR&#xff0c;反射系数&#xff0c;插入损耗&#xff0c;隔离度 &#x1f4a2;S参数&#x1f4a2;&#x1f4a2;S11与return loss&#xff0c;VSWR&#xff0c;反射系数&#x1f4a2;&#x1f4a2;S21&#xff0c;插入损耗和增益&#…...

强化学习的几个主要方法(策略梯度、PPO、REINFORCE实现等)(上)

本笔记有大量参考蘑菇书EasyRL https://datawhalechina.github.io/easy-rl/#/ 包括其配图和部分文本。 1. 基本概念 1.1 基本流程 强化学习是一种学习框架&#xff0c;其中智能体&#xff08;Agent&#xff09; 通过与 环境&#xff08;Environment&#xff09; 的交互&#…...

Git远程仓库操作

文章目录 远程仓库连接Gitee克隆代码 多人协同问题说明 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Git专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月1日13点10分 远程仓库 Git 是分布式版本控制系统&#xff0c;同一个 Git …...

GAGAvatar: Generalizable and Animatable Gaussian Head Avatar 学习笔记

1 Overall GAGAvatar&#xff08;Generalizable and Animatable Gaussian Avatar&#xff09;&#xff0c;一种面向单张图片驱动的可动画化头部头像重建的方法&#xff0c;解决了现有方法在渲染效率和泛化能力上的局限。 旋转参数 现有方法的局限性&#xff1a; 基于NeRF的方…...

什么是VISUAL STUDIO CODE (V S CODE)

Visual Studio Code&#xff08;简称VS Code&#xff09;是由微软开发的一个免费的、开源的源代码编辑器。它是一个轻量级但功能强大的工具&#xff0c;支持多种编程语言和框架&#xff0c;广泛用于开发各种应用程序&#xff0c;尤其是Web开发。VS Code具备以下特点&#xff1a…...

2024年09月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析

青少年软件编程(Python)等级考试试卷(三级) 分数:100 题数:38 一、单选题(共25题,共50分) 1. 以下表达式的值为True的是?( ) A. all( ,1,2,3) B. any([]) C. bool(abc) D. divmod(6,0)...

C++初阶——动态内存管理

目录 1、C/C内存区域划分 2、C动态内存管理&#xff1a;malloc/calloc/realloc/free 3、C动态内存管理&#xff1a;new/delete 3.1 new/delete内置类型 3.2 new/delete自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 5.1 内置类型 5.2 自定…...

如何查看阿里云ddos供给量

要查看阿里云上的 DDoS 攻击量&#xff0c;你可以通过阿里云的 云盾 DDoS 防护 服务来进行监控和查看攻击数据。阿里云提供了详细的流量监控、攻击日志以及攻击趋势分析工具&#xff0c;帮助用户实时了解 DDoS 攻击的情况。以下是九河云总结的查看 DDoS 攻击量的步骤&#xff1…...

MySQL中的事务隔离全详解

第一部分&#xff1a;MySQL事务的特性与并行事务引发的问题 1. 什么是事务及其四大特性&#xff08;ACID&#xff09;&#xff1f; 事务&#xff08;Transaction&#xff09;是数据库操作的基本单位&#xff0c;它将一组操作组合在一起&#xff0c;以确保这些操作作为一个整体…...

异常--C++

文章目录 一、异常的概念及使用1、异常的概念2、异常的抛出和捕获3、栈展开4、查找匹配的处理代码5、异常重新抛出6、异常安全问题7、异常规范 二、标准库的异常 一、异常的概念及使用 1、异常的概念 异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并…...

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发&#xff0c;开发自己的软件&#xff0c;例如&#xff1a;【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等&#xff0c;不管是您用来个人学习还是公司研发需求&#xff0c;都相当合适&#xff0c;包您满…...

锁-读写锁-Swift

实现一 pthread_mutex_t&#xff1a; ReadWriteLock/Sources/ReadWriteLock at main SomeRandomiOSDev/ReadWriteLock GitHub https://swiftpackageindex.com/reers/reerkit/1.0.39/documentation/reerkit/readwritelock/ // // Copyright © 2022 reers. // // Pe…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...