C++|树形关联式容器(set、map、multiset、multimap)介绍使用

目录

一、关联式容器介绍

1.1概念

1.2键值对

1.3树形结构的关联式容器

 1.3.1pair模板介绍 

1.3.2make_pair的介绍 

二、set的介绍和使用

2.1set介绍

2.2set使用

 2.2.1构造 

2.2.2容量

2.2.3修改

三、map的介绍和使用 

 3.1map介绍

 3.2map使用

 3.2.1构造

3.2.2容量

3.2.3修改

四、multiset和multimap简单介绍使用


一、关联式容器介绍

1.1概念

我们之前学过的STL中的部分容器,比如:string、vector、list、deque等。这些都是序列式容器,他们都是线性序列的数据结构,里面存储的是元素本身。

关联式容器:也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key,value>结构的键值对,在数据检索时比序列式容器效率更高

1.2键值对

在搜索二叉树中的kv模型已经介绍过了键值对了,它是用来表示具有一一对应关系的结构,该结构中包含两个成员变量,key和value,key代表键值,value表示与key对应的信息。比如:建立英汉词典互译、统计value出现的次数 

1.3树形结构的关联式容器

 为了更好的管理数据,STL设计了两种不同结构的管理式容器:树形结构与哈希结构。树形结构的关联式容器主要有四种:map、set、multimap、multiset。他们的底层采用都是平衡搜索树(即红黑树)来实现,容器中的元素是有序的序列。那么接下来在学习他们的用法前,先介绍一下pair,以方便后续理解set,map使用。在下一章节,将会模拟实现他们。

 1.3.1pair模板介绍 

pair有两个模板参数,pair类中有两个元素first,second,分别为T1,T2类型。其中T1被typedef成first_type,T2被typedef成second_type。其中,元素first,second可以修改。对于set,虽然其key值不存在pair当中,但有接口的返回值类型是pair类型。对于map,其值key和value存放在pair中。

函数声明功能介绍
pair();
构造空pair
template<class U, class V> pair (const pair<U,V>& pr);
拷贝构造
pair (const first_type& a, const second_type& b);
分别用两个值初始化pair,即分别初始化pair中的first和second元素
pair& operator= (const pair& pr);
通过对象进行赋值

例子: 

#include <iostream>
using namespace std;

int main()
{

	pair<int, int> p(1, 2);//初始化pair

	cout << p.first << " " << p.second << endl;

	pair<int, int> pp(p);//拷贝构造

	pp.first = 3;
	pp.second = 4;
	cout << pp.first << " " << pp.second << endl;

	pair<int, int> ret = pp;//赋值
	ret.first = 5;
	ret.second = 6;
	cout << ret.first << " " << ret.second << endl;

	return 0;
}

输出结果: 

 

1.3.2make_pair的介绍 

make_pair其实就是一个pair对象。其实现如下 

根据其实现,pair<T1,T2>(x,y) 构造了一个默认pair对象并返回,也就是说,make_pair(T1 x, T2 y) == pair<T1,T2>(x,y) 。所以make_pair即一个pair对象,采用make_pair的好处就是简短了一点。

例如:

#include <iostream>
using namespace std;

int main()
{

	pair<int, int> p(make_pair<int,int>(1,2));//make_pair即一个pair对象,将该对象拷贝给p

	cout << p.first << " " << p.second << endl;

	return 0;
}

 输出结果:

go on~ 

二、set的介绍和使用

2.1set介绍

1.set是按照一定次序存储元素的容器,C++中是按中序遍历的。

2.在set中,元素key与value是一一对应的,且是唯一的。set中的key不能在容器中修改(元素总是const),但是可以插入和删除。因为修改元素,就破坏了树的结构。

3.在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。元素的相对顺序是严格确定的。

4.set容器通过key访问单个元素的速度通常比unordered_set(哈希实现)容器慢,但他们允许根据顺序对子集直接迭代。

5.set在底层是用红黑树实现的。

注意:

1.与map/multimap不同,map/multimap中存储的是真正的键值对<key,value>,set中只放value,但在底层实际存放的是由<value,value>构成的键值对。

2.set实际使用不需要构造键值对,只需传value参数即可。

3.set中的元素不可以重复,所以在插入相同的元素时,set会进行去重

4.使用set的迭代器遍历元素,得到的是有序序列,因为set底层是以中序的方式遍历

5.set中的元素默认按照小于来比较

6.set中查找某个元素,时间复杂度为:log N

7.红黑树依然是搜索二叉树,只不过其实现二叉搜索树的方式不同,优化了最初的二叉搜索树的缺点。 

set的第一个参数,存放元素的类型,第二个参数表示set元素默认按照小于来比较,第三个参数表示元素空间的管理方式,这个先不做了解,不影响我们的使用模拟实现。

2.2set使用

 2.2.1构造 

函数声明功能介绍
explicit set (const key_compare&comp=key_compare(),const allocator_type& alloc = allocator_type());
构造空set
template <class InputIterator>
  set (InputIterator first, InputIterator last,
       const key_compare& comp = key_compare(),
       const allocator_type& alloc = allocator_type());
用[first,last)区间中的元素构造set
set (const set& x);
拷贝构造

例子: 

#include <iostream>
#include <set>
using namespace std;


int main()
{
	int arr[] = { 2,34,6,6,56,8,321,9,4,88 };

	set<int> s(arr, arr + sizeof(arr)/sizeof(arr[0]));//迭代器区间构造

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;

	set<int> s1(s);//拷贝构造
	for (auto e : s1)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

输出结果: 

 

2.2.2容量

函数声明功能介绍
bool empty() const;
检测set是否为空,空返回true,否则返回false
size_type size() const;
返回set中有效元素的个数
size_type max_size() const;
返回set能够存储的最大容量

例子: 

#include <iostream>
#include <set>
using namespace std;


int main()
{
	int arr[] = { 2,34,6,6,56,8,321,9,4,88 };

	set<int> s(arr, arr + sizeof(arr) / sizeof(arr[0]));//迭代器区间构造

	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;
	
	cout << boolalpha << s.empty() << endl;//bool值形式打印
	cout << s.size() << endl;
	cout << s.max_size() << endl;

	return 0;
}

输出结果: 

 

2.2.3修改

函数声明功能介绍
pair<iterator,bool> insert(const value_type& x)在set中插入元素x,实际插入的是<x,x>构成的键值对,如果插入成功,返回<该元素在set中的位置,true>,失败,说明x在set中已经存在,返回<x在set中的位置,false>
void erase(iterator position)删除迭代器所指向position位置上的元素
size_type erase(const key_type& x)删除set中值为x的元素,返回删除的元素的个数
void erase(iterator first,iterator last)删除迭代器区间[first,last)中的元素
void swap(set& st)交换两个set中的元素
void clear()将set中的元素清空
iterator find(const key_type& x) const返回set中值为x的元素的位置,未找到,返回end()
size_type count(const key_type& x) const返回set中值为x的元素个数,因为set会去重,所以要么返回1,要么返回0

 其中key_type 代表第一个模板参数类型,即T

例子: 

#include <iostream>
#include <set>
using namespace std;


int main()
{
	int arr[] = { 2,34,6,6,8,9,4};

	set<int> s(arr, arr + sizeof(arr) / sizeof(arr[0]));//迭代器区间构造
	
	set<int>::iterator it = s.begin();
	while(it != s.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	
	it= s.find(6);//返回元素的当前位置
	cout << *it << endl;
	cout << s.count(6) << endl;
	
	size_t num = s.erase(6);
	cout << num << endl;

	s.erase(s.begin());//删除迭代器当前位置元素
	it = s.begin();

	while (it != s.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	s.erase(s.begin(), s.end());//删除迭代器区间中的元素

	return 0;
}

输出结果: 

三、map的介绍和使用 

 3.1map介绍

 

1.map是关联式容器,存储由键值key和value组合的元素。key和value的组合元素跟set一样依然是按照key来进行比较排序。

2.在map中,key和value是一一对应的,即使类型不同。由于他们绑定在一起,并为他们取名为pair<key,value>,所以对于map而言Key和value元素存放在pair<const key, T>类模板当中。其typedef pair<const key, T> value_type;

3.map中通过键值访问单个元素的速度通常比unordered_map(哈希实现,遍历顺序是无序的)容器慢,但map遍历顺序是有序的。

4.map支持下标访问,通过key访问,即在[]中放入key,就可以找到key对应的value。

5.map由红黑树实现。

第一个参数表示key的类型,第二个参数表示value的类型。第三个参数表示map中的元素默认是按key来比较,且按小于来比。第四个参数表示空间配置器。

 3.2map使用

 3.2.1构造

函数声明功能介绍
explicit map (const key_compare&comp=key_compare(),const allocator_type& alloc = allocator_type());
构造空map
template <class InputIterator>
  map (InputIterator first, InputIterator last,
       const key_compare& comp = key_compare(),
       const allocator_type& alloc = allocator_type());
用[first,last)区间中的元素构造map
map (const map& x);
拷贝构造
map& operator= (const map& x);
map& operator= (initializer_list<value_type> il);

通过对象进行初始化。

通过初始化列表进行初始化,C++11的用法

例子: 

#include <iostream>
#include <map>
using namespace std;


int main()
{
	map<string, string> mp = { {"apple","苹果"}, {"banana","香蕉"}, {"orange","橙子"} };//初始化列表进行初始化,每个元素都是pair类型
	for (auto& e : mp)//访问map元素,实则就是pair中的元素
	{
		cout << e.first << ":" << e.second << endl;
	}
	cout << endl;

	map<string, string> mmp(mp.begin(), mp.end());//迭代器区间构造

	map<string, string>::iterator it = mmp.begin();

	while (it != mmp.end())
	{
		cout << it->first << ":" << it->second << endl;
		it++;
	}
	cout << endl;

	map<string, string> pm(mmp);//拷贝构造
	for (auto& e : pm)
	{
		cout << e.first << ":" << e.second << endl;
	}

	return 0;
}

 输出结果:

3.2.2容量

函数声明功能简介
bool empty() const;
检测map中元素是否为空,是,返回true,否,返回false
size_type size() const;
返回map中有效元素的个数
mapped_type& operator[] (const key_type& k);

返回key对应的value。(支持插入,修改。若key不存在,则插入value,并返回。若存在,修改value,并返回)

mapped_type& at (const key_type& k);

const mapped_type& at (const key_type& k) const;
返回key对应的value。(支持修改,不支持插入。若key不存在,抛异常。若存在,修改value,并返回)

 其中,mapped_type类型是第二个模板参数的类型,即T。

例子: 

#include <iostream>
#include <map>
using namespace std;


int main()
{

	map<string, int> mp = { {"one",1},{"two",2},{"three",3},{"four",4} };

	cout << boolalpha << mp.empty() << endl;
	cout << mp.size() << endl;

	cout << "mp[one]:" << mp["one"] << endl;//返回对应的value
	cout << "mp[two]:" << mp["two"] << endl;
	cout << "mp[three]:" << mp["three"] << endl;
	cout << "mp[four]:" << mp["four"] << endl << endl;

	mp["one"] = 5;//修改value
	mp["two"] = 6;
	mp["three"] = 7;
	mp["four"] = 8;

	mp["nine"] = 9;//mp对象中没有<nine,9>。则表示新建key,插入9
	mp["ten"] = 10;
	cout << "mp[one]:" << mp["one"] << endl;//返回对应的value
	cout << "mp[two]:" << mp["two"] << endl;
	cout << "mp[three]:" << mp["three"] << endl;
	cout << "mp[four]:" << mp["four"] << endl;
	cout << "mp[nine]:" << mp["nine"] << endl;
	cout << "mp[ten]:" << mp["ten"] << endl;

	return 0;
}

输出结果: 

 

3.2.3修改

函数声明功能介绍
pair<iterator,bool> insert(const value_type& x)在map中插入键值对x,注意x是一个键值对,即pair类型,返回值也是键值对:iterator代表新插入元素的位置,bool代表插入成功

void erase(iterator position)

size_type erase(const key_type& x)

void erase(iterator first,iterator last)

删除position位置上的元素

删除键值为x的元素

删除[first,last)区间中的元素

void swap(map<Key,T,Compare,Allocator>& mp)交换两个map中的元素
void clear()将map中的元素清空

iterator find(const key_type& x)

const_iterator find(const key_type& x) const

在map中插入key为x的元素,找到返回该元素的位置的迭代器,否则返回end()

在map中插入key为x的元素,找到返回该元素的位置的const迭代器,否则返回end()

size_type count(const key_type& x)返回key为x的键值在map中的个数,注意map汇总key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中

对于operator[]重载实现,实则是按如下:

 

由于该长代码不好理解,将上述进行拆写,那么该重载的实现,可以按以下方式:

	mapped_type& operator[](const k& key)
	{
        //插入成功,iterator指向的就是插入成功的位置,该位置类型为pair类型。插入失败,说明已经存在,iterator指向的就是已经存在的位置。
		pair<iterator, bool> p = this->insert(make_pair(k,mapped()));

        //p.first就是迭代器对象,指向<k,value>所在位置,p.first->second就是value
		return p.first->second;
	}

接下来,就对修改的操作进行演示:

#include <iostream>
#include <map>
using namespace std;


int main()
{

	map<string, string> mp;
	mp.insert(pair<string, string>("insert", "插入"));//将<"insert","插入">插入map中,用pair构造键值对
	//mp.insert(make_pair("insert","插入"));

	//通过make_pair构造键值对
	mp.insert(make_pair("fruit", "水果"));

	pair<map<string,string>::iterator, bool> p = mp.insert(make_pair("fruit", "水果"));//已经存在<"fruit","水果">,返回false
	cout << boolalpha << p.second << endl;

	//通过operator[]向map中插入元素
	mp["apple"] = "苹果";
	//mp.at("peach") = "桃子";//"peach"不存在会抛异常,不会插入


	map<string, string> m;
	m.swap(mp);

	cout << boolalpha << mp.empty() << endl;
	
	m.erase("apple");
	map<string, string>::iterator it = m.find("apple");
	if (it != m.end())
	{
		cout << "苹果存在" << endl;
	}
	else
	{
		cout << "苹果不存在" << endl;
	}

	cout << m.count("peach") << endl;
	return 0;
}

 输出结果:

 总结一下map:

1.map中的元素是键值对,由pair管理。

2.map中的key是唯一的。

3.默认按照小于的方式对key进行比较

4.map中的元素是按中序的方式打印的,即有序的。

5.[]操作符,可插入,可修改。

四、multiset和multimap简单介绍使用

multiset和multimap跟set和map的使用一样。唯一功能不一样的是,multiset和multimap中的key不去重,正因为有了不去重的功能,所以对于他们就没必要提供operator[],因为该接口是先判断是否已经存在key,是,则返回key对应的value,可以进行对value修改,而不是继续插入key,否,则是新插入key,这就达到了去重的概念。所以他们不提供该接口,而对于其他接口的用法和set、map是类似的。

multiset: 

#include <iostream>
#include <set>
using namespace std;


int main()
{
	string arr[] = { "apple","apple","banana","apple","orange","grape","peach" };
	multiset<string> s(arr, arr + sizeof(arr)/sizeof(arr[0]));//不去重

	for (auto& e : s)
	{
		cout << e << endl;
	}
	
	return 0;
}

输出结果: 

 

multimap:

#include <iostream>
#include <map>
using namespace std;


int main()
{
	multimap<string, string> mlp = { {"apple","苹果"},{"apple","苹果"},{"orange","橙子"},
					{"peach","桃子"},{"grape","葡萄"},{"apple","苹果"},{"banana","香蕉"} };

	for (auto& e : mlp)
	{
		cout << e.first << ":" << e.second << endl;
	}

	mlp.insert(make_pair("peach","桃子"));
	mlp.erase("apple");//删除所有apple
	multimap<string, string>::iterator it = mlp.find("apple");
	if (it != mlp.end())
	{
		cout << "apple is also exist" << endl;
	}
	else
	{
		cout << "apple is not exist" << endl;
	}

	return 0;
}

 输出结果:

对于他们的底层实现会在之后的章节进一步实现,最后封装map和set 

end~ 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VC++6.0 Sqlite3调用例子

1,为什么要使用Sqlite3? SQLite 是一个软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。 2,为什么使用SQLite version 3.8.4.3 2014-04-03 16:53:12的版本…

邮件发送API的功能有哪些?API的调用限制?

邮件发送API的响应速度如何&#xff1f;如何选择API发送邮件&#xff1f; 邮件发送API提供了高效、灵活且可靠的邮件发送功能&#xff0c;使得邮件营销、用户通知、系统告警等场景变得轻松自如。那么&#xff0c;邮件发送API具体都有哪些功能呢&#xff1f;让AokSend来探索吧&…

Spark SQL ---结构化数据文件处理

DataFrame概述 DataFrame的创建 创建DataFrame的两种基本方式&#xff1a; •已存在的RDD调用toDF()方法转换得到DataFrame。 •通过Spark读取数据源直接创建DataFrame。 若使用SparkSession方式创建DataFrame&#xff0c;可以使用spark.read从不同类型的文件中加载数据创建…

【美团面试2024/05/14】前端面试题滑动窗口

一、题目描述 设有一字符串序列 s&#xff0c;确定该序列中最长的无重复字母的子序列&#xff0c;并返回其长度。 备注 0 < s.length < 5 * 104 s 由英文字母、数字、符号和空格组成 示例1 输入 s "abcabcbb" 输出 3 二、原题链接 这道题在LeetCode上的原题链…

运维别卷系列 - 云原生监控平台 之 06.prometheus pushgateway 实践

文章目录 [toc]Pushgateway 简介Pushgateway 部署创建 svc创建 deployment Pushgateway 测试删除 Pushgateway 上对应 lable 的数据 Pushgateway 简介 WHEN TO USE THE PUSHGATEWAY Pushgateway 是一种中介服务&#xff0c;允许您从无法抓取的作业中推送指标。 The Pushgateway…

Python NumPy数组的创建方法

Numpy是Python中科学计算的基础包&#xff0c;其核心对象就是ndarray&#xff08;n维数组&#xff09;。利用数组可以快速执行逻辑&#xff0c;形状操作&#xff0c;统计和傅里叶变换等运算&#xff0c;其效率比Python原生的数组效率更高。因此使用Numpy的第一件事就是创建Nump…

构建第一个ArkTS应用之@LazyForEach:数据懒加载

LazyForEach从提供的数据源中按需迭代数据&#xff0c;并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach&#xff0c;框架会根据滚动容器可视区域按需创建组件&#xff0c;当组件滑出可视区域外时&#xff0c;框架会进行组件销毁回收以降低内存占用。 接口…

线性/非线性最小二乘 与 牛顿/高斯牛顿/LM 原理及算法

最小二乘分为线性最小二乘和非线性最小二乘 最小二乘目标函数都是min ||f(x)||2 若f(x) ax b&#xff0c;就是线性最小二乘&#xff1b;若f(x) ax2 b / ax2 bx 之类的&#xff0c;就是非线性最小二乘&#xff1b; 1. 求解线性最小二乘 【参考】 2. 求解非线性最小二乘…

玩转大模型 企业AI着陆新正解 神州问学AI原生赋能平台正式发布

在人工智能技术日新月异的今天&#xff0c;神州数码凭借深厚的行业洞察和技术积累&#xff0c;揭开了AI原生赋能平台——神州问学的神秘面纱。作为企业AI着陆的加速引擎&#xff0c;神州问学致力于通过AI原生场景赋能&#xff0c;为企业开辟一条通往智能未来的坦途。 神州问学—…

出国旅游常用英语,柯桥成人英语培训

Where can I catch a taxi?哪里我可以叫到出租车&#xff1f; The taxi zone is right on the left corner over there.出租车站台就在左边转角处。 Are you free?您有空吗&#xff1f; Sure. Where are you going?当然。您要去哪里&#xff1f; Drive me back to Santa …

2024年淘宝京东天猫618红包领取跨店满减优惠券活动时间是从什么时候开始到几月几号结束?

2024年淘宝、天猫、京东618红包领取口令及活动时间已发布&#xff0c;具体如下&#xff1a; 一、2024年淘宝天猫618活动 1.1、2024年淘宝天猫618活动时间 2024年5月20日开始持续到6月20日结束&#xff1b; 1.2、2024年淘宝天猫618红包领取 在活动时间内&#xff0c;每天都可…

如何通过radsystem源代码启动项目

大家有没有想过这样一个问题&#xff0c;如果别人没有下载radsystems&#xff0c;别人该如何打开我们的项目呢&#xff0c;那么今天我来介绍一下&#xff0c;如何启动radsystem源代码。 一般来说我们都是需要打开radsystems的publish部署项目 但是我们可以通过它部署后的源代码…

内存函数:memcpy(拷贝),memmove(拷贝),memcmp(比较),memset(设置)

内存函数 一.memcpy&#xff08;内存拷贝1&#xff09;1.函数使用2.模拟实现 二.memmove&#xff08;内存拷贝2&#xff09;1.函数使用2.模拟实现 三.memcmp&#xff08;内存比较&#xff09;1.函数使用2.模拟实现 四.memset&#xff08;内存设置&#xff09;1.函数使用2.模拟实…

axios封装 手动取消接口请求

axios封装 手动取消接口请求 1.创建clearHttpRequest.js文件2.封装的axios文件中使用3.vue文件中引入4. 路由切换使用 对于一些接口loading很久&#xff0c;用户想手动终止请求的需求&#xff0c; 并为了节约性能&#xff0c;当路由切换时&#xff0c;cancel掉还没有结束的接口…

Redis经典问题:BigKey问题

大家好,我是小米,今天来和大家聊聊Redis中的一个经典问题:BigKey问题。在互联网系统中,我们经常需要保存大量的用户数据,比如用户的个人信息、粉丝列表、发表的微博内容等等。这些数据往往会被存储在Redis这样的缓存系统中,以提高系统的性能和响应速度。但是,在处理这些…

算法考试题

分治法课堂案例 第1关&#xff1a;二分搜索技术 任务描述 本关任务&#xff1a;给定一组有序整数&#xff0c;用二分查找技术查找X是否在序列中&#xff0c;在则输出Yes&#xff0c;不在则输出No。 输入格式&#xff1a;三行&#xff0c;第一行一个整数n&#xff0c;第二行…

相机模型的内参、外参

相机模型的内参、外参 文章目录 相机模型的内参、外参1. 针孔模型、畸变模型&#xff08;内参&#xff09;2. 手眼标定&#xff08;外参&#xff09; Reference 这篇笔记主要参考&#xff1a;slam十四讲第二版&#xff08;高翔&#xff09; 相机将三维世界中的坐标点&#xff…

2024年加密软件市场大比拼:谁将成为数据保护的新星

在2024年的加密软件市场&#xff0c;一场激烈的竞争正在上演。各大厂商纷纷推出自家的最新产品&#xff0c;旨在为用户提供更加安全、可靠的数据保护方案。在这场大比拼中&#xff0c;谁将成为数据保护的新星&#xff0c;引领市场的新潮流呢&#xff1f; 首先&#xff0c;我们…

收藏与品鉴:精酿啤酒的艺术之旅

啤酒&#xff0c;这一古老的酒精饮品&#xff0c;不仅是人们生活中的日常饮品&#xff0c;更是一种艺术和文化的载体。对于Fendi club啤酒而言&#xff0c;收藏与品鉴更是一门深入骨髓的艺术之旅。 Fendi club啤酒的收藏&#xff0c;不仅仅是简单的存放和保管&#xff0c;而是一…

阿里云域名备案流程

阿里云域名备案流程大致可以分为以下几个步骤&#xff0c;这些信息综合了不同来源的最新流程说明&#xff0c;确保了流程的时效性和准确性&#xff1a; UP贴心的附带了链接&#xff1a; 首次备案流程&#xff1a;ICP首次备案_备案(ICP Filing)-阿里云帮助中心 (aliyun.com) …