C++之STL

2023-05-16

定义

STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。
STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组;
STL另一个重要特性是它不是面向对象的。为了具有足够通用性,STL主要依赖于模板而不是封装,继承和虚函数(多态性)——OOP的三个要素。你在STL中找不到任何明显的类继承关系。这好像是一种倒退,但这正好是使得STL的组件具有广泛通用性的底层特征。另外,由于STL是基于模板,内联函数的使用使得生成的代码短小高效;
从逻辑层次来看,在STL中体现了泛型化程序设计的思想,引入了诸多新的名词,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。与OOP(object-oriented programming)中的多态(polymorphism)一样,泛型也是一种软件的复用技术;从实现层次看,整个STL是以一种类型参数化的方式实现的,这种方式基于一个在早先C++标准中没有出现的语言特性–模板(template)。

组件

1)容器(Container),是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;

#include<iostream>
#include <numeric>
#include <algorithm>
#include <iterator>
#include<string>
#include<vector>
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <stack>
#include <queue>
#include <map>  
#include <unordered_map>
#include <set>
#include <unordered_set>

using namespace std;

int main()
{
	/*顺序容器*/
	//共同方法
	std::vector<int> con;
	//得到首尾迭代器,返回类型为iterator
	con.begin(), con.end();
	//得到首尾常量迭代器,返回类型为const_iterator
	con.cbegin(),con.cend();
	//得到首尾逆迭代器,返回类型为reverse_iterator, forward_list没有该方法
	con.rbegin(), con.rend();
	//得到容器内元素个数,forward_list没有该方法
	con.size();
	//清空容器,array没有该方法
	con.clear();



	//1:array - 与数组类似,但更安全,并且可以使用标准算法
	//包含头文件 #include <array>
	//创建一个固定大小的array,跟数组类似,这个大小不可改变
	array<int, 5> ary;

	//[]或at访问对应位置的元素,at比[]安全,因为at进行下标检查
	ary[0] = ary.at(0);
	for (int i = 0; i < ary.size(); ++i)
	{
		// cout<< "数组的逐个元素" << ary[i] << "\n";
	}
	



	//2:vector - 向量,动态数组,可自动扩充容量。随机访问快,除尾部之外的增减慢。
	//包含头文件 #include <vector>

	//创建一个可容纳int的vector,其他类型类似
	vector<int> vec;

	//末尾添加一个元素
	vec.push_back(1);
	vec.push_back(2);
	vec.push_back(3);

	//从末尾删去一个元素
	// vec.pop_back();

	//在指定位置插入一个元素, 第一个元素为vector<int>::const_iterator类型
	//insert采用拷贝的方式添加元素,emplace则采用直接构造的方式添加元素
	vec.insert(vec.cbegin(), 2);
	// vec.emplace(vec.cbegin(), 0);

	//删去指定位置的元素,参数为vector<int>::const_iterator类型
	vec.erase(vec.cbegin());

	//使用下标或者使用at访问对应位置的元素
	// vec[0] = vec.at(0);
	for (int i = 0; i < vec.size(); ++i)
	{
		// cout<< "向量的逐个元素" << vec[i] << "\n";
	}

	//2.1二维向量
	 vector<pair<int, int>> vec2;
	 for(int i = 0; i < 10; i++){
	 	vec2.emplace_back(make_pair(10-i,i));
	 }
	 for(int j=0; j<vec2.size(); j++){
	 	cout << "二维向量" << vec2[j][0] << vec2[j][j] << endl;
	 }



	//3:deque - 双向动态数组,可以看成vector的双向版本
	//需要包含的头文件#include <deque>

	//创建可容纳int元素的deque
	deque<int> dq;

	//头插和头删
	dq.push_front(1), dq.pop_front();

	//尾插和尾删
	dq.push_back(2), dq.pop_back();

	//在指定位置插入
	dq.insert(dq.cbegin(), 1);
	// dq.emplace(dq.cbegin(), 1);

	//删除指定位置的元素
	dq.erase(dq.cbegin());

	//使用下标或at访问指定位置的元素
	// dq[0] = dq.at(0);
	for (int i = 0; i < dq.size(); ++i)
	{
		// cout<< "队列的逐个元素" << dq.at(i) << "\n";
	}




	//4:forward_list - 单向链表,唯一不提供size()方法,并且插入和删除都是在给定位置之后
	//包含头文件#include <forward_list>

	//创建可以容纳int元素的forward_list
	forward_list<int> fl;

	//头插
	fl.push_front(1);	
	fl.push_front(2);
	fl.push_front(3);
	fl.push_front(4);
	fl.push_front(5);
	fl.push_front(6);
	fl.push_front(7);
	fl.push_front(8);
	fl.push_front(9);
	fl.push_front(10);

	//头删
	// fl.pop_front();

	//删除容器中所有等于val的元素
	fl.remove(5);

	//插入指定位置之后的元素,在这里,如果fl非空,则2成为第二个元素
	fl.insert_after(fl.cbegin(), 2);
	// fl.emplace_after(fl.cbegin(), 2);

	//删除指定位置之后的元素,在这里,删除第二个元素
	fl.erase_after(fl.cbegin());

	int size = distance(fl.begin(),fl.end());
	// cout << "单向链表的大小" << size << "\n";


	forward_list<int>::iterator i;

    for (i = fl.begin(); i != fl.end(); ++i){
        // cout << "单向链表中逐个元素" << *i << "\n";
    }
	

	//5:list - 双向链表,支持双向插入删除,只支持顺讯访问,增删块
	//需要包含头文件#include <list>

	//创建一个容纳int的list
	list<int> lst;

	//头插或尾插
	lst.push_front(1), lst.push_back(2);
	lst.push_front(3), lst.push_back(4);
	lst.push_front(5), lst.push_back(6);

	//头删或尾删
	lst.pop_front(), lst.pop_back();

	//在指定位置插入
	lst.insert(lst.cbegin(), 1);
	// lst.emplace(lst.cbegin(), 1);


	//在指定位置删除
	lst.erase(lst.cbegin());	

	list<int>::iterator j;

    for (j = lst.begin(); j != lst.end(); ++j){
        cout << "链表中逐个元素" << *j << "\n";
    }





    //6:stack - 栈,先进后出,默认容器为deque,vector和list,并且不允许遍历
	//包含的头文件#include <stack>

	//创建一个能容纳int元素的stack
	stack<int> s;

	//将一个元素入栈
	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4);
	s.push(5);

	//返回栈顶元素
	cout << "栈顶元素" << s.top() << "\n";

	//将栈顶元素出栈
	s.pop();

	cout << "出栈后栈顶元素" << s.top() << "\n";

	cout << "栈的大小" << s.size() << "\n";
	cout << "栈是否为空" << s.empty() << "\n";


	
	//7:queue - 队列,先进先出,默认容器为deque,vector和list,并且不允许遍历
	//包含头文件#include <queue>

	//创建可容纳int型元素的queue
	queue<int> q;

	//使一个元素入队
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);

	//使第一个元素出队
	q.pop();

	//返回队首元素
	cout << "队首元素" << q.front() << "\n";

	//返回队尾元素
	cout << "队尾元素" << q.back() << "\n";

	cout << "队列的大小" << q.size() << "\n";
	cout << "队列是否为空" << q.empty() << "\n";


    //8: priority_queue -优先队列,其底层是用堆来进行实现的,默认规则就是优先级最高的放在队首,优先级对它们的设置默认都是数字大的优先级越高,队首元素就是优先队列内元素最大的那个
	/*定义:priority_queue<Type, Container, Functional>
	Type 就是数据类型。(int ,double等.)
	Container 就是容器类型(Container必须是用数组实现的容器,默认vector,但不能用 list。)
	Functional 就是比较的方式(可以自定义,默认从小到大排序)
	*/
	// priority_queue<int, vector<int>, less<int> > p1 这样声明降序排序
	// priority_queue<int, vector<int>, greater<int> > p1 这样声明升序排序
	priority_queue<int> p1; // 默认为降序排序
	p1.push(1);
	p1.push(3);
	p1.push(5);
	p1.push(7);
	p1.push(8);
	p1.push(2);
	//队列中的内容会自动排序: 8,7,5,3,2,1;

	cout << "队头元素" << p1.top() << endl;
	p1.pop();
	cout << "队头元素" << p1.top() << endl;
	p1.pop();
	cout << "队头元素" << p1.top() << endl;
	p1.pop();
	cout << "队头元素" << p1.top() << endl;
	p1.pop();
	cout << "队头元素" << p1.top() << endl;



	/*关联容器*/
	//共有八种,分为两大类:map和set.他们的共同方法有begin(),end()和size()等

	//1:map
	//1.1 : map - 关联数组,保存键值对,数据存放是有序的
	//1.2 : multimap - 关键字可重复出现的map。
	//1.3 : unordered_map:使用hash函数的map,数据存放是无序的。
	//1.4 : unordered_multimap:在unordered_map的基础上,关键字可重复出现。
	//包含头文件
	//map和multimap需包含<map>
	// #include <map>  
	//unordered_map和unordered_multimap需包含<unordered_map>        
	// #include <unordered_map>

	//创建一个key为string元素,value为int元素的map
	map<string, int> m;

	//向m中添加一个键值对,map的value_type为对应的pair,下列四种方式均可
	m.insert(pair<string, int>("hello", 1));
	m.insert(make_pair("hello", 1));
	// m.emplace("hello", 1);
	m["hello"] = 1;

	//查看map中是否有指定的key,若没有,则返回尾后迭代器
	m.find("hello");
	//查看某个key所对应的value
	//使用下标,如果没有key为"world"的键值对,则创建("world", 0)键值对并添加至这个map
	m["world"];
	//使用at,若没有该键值对,则报错
	m.at("world");

	//最好的访问方法为,先判断有没有该键值对,若有,再进行访问
	if (m.find("world") != m.end())
	    cout << m["world"] << endl;

	//删除key为“hello”的键值对,不管是否有该键值对,都不会报错
	m.erase("hello");


	//2:set
	//2.1: set - 只保留关键字的容器(关键字即值)。
	//2.2: multiset - 关键字可重复出现
	//2.3: unordered_set - 无序的set
	//2.4: unordered_multiset - 在unordered_set的基础上关键字可重复。
	//需包含的头文件
	//set和multiset需要包含<set>
	// #include <set>
	//unordered_set和unordered_multiset需要包含<unordered_set>
	// #include <unordered_set>

	//创建一个能容纳int型元素的set
	set<int> se;

	//插入一个元素
	se.insert(2);
	// se.emplace(3);

	//找到指定关键字位置
	se.find(2);

	//删除关键字
	se.erase(2);
	

	return 0;
}

2)迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator()以及其他类似于指针的操作符地方法的类对象;*

//迭代器 : 是一个所谓的智能指针,具有遍历复杂数据结构的能力。

//每一种容器都必须提供自己的迭代器,事实上每种容器都将其迭代器以嵌套的方式定义于内部。
//因此各种迭代器的接口相同,型号却不同,这就是所谓的泛型程序设计的概念:所用的操作行为都使用相同的接口,虽然他们的具体实现不同。


#include<iostream>
#include<string>
#include<vector>

using namespace std;

int main()
{
	std::vector<string> names;

	names.push_back("龚港浩");
	names.push_back("王雪茗");

	std::vector<string> ::iterator iter = names.begin();

	while(iter != names.end())
	{
		cout << *iter << "\n";
		++iter;
	}
	return 0;
}

3)算法(Algorithm),是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
STL中算法大致分为四类:
1、非可变序列算法:指不直接修改其所操作的容器内容的算法。
2、可变序列算法:指可以修改它们所操作的容器内容的算法。
3、排序算法:包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
4、数值算法:对容器内容进行数值计算。
查找算法 - 判断容器内是否包含某个值

方法含义
adjacent_find在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的ForwardIterator。否则返回last。重载版本使用输入的二元操作符代替相等的判断。
binary_search在有序序列中查找value,找到返回true。重载的版本实用指定的比较函数对象或函数指针来判断相等。
count利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数。
count_if利用输入的操作符,对标志范围内的元素进行操作,返回结果为true的个数
equal_range功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound
find利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的一个InputIterator。
find_end在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一个ForwardIterator,否则返回输入的"另外一对"的第一个ForwardIterator。重载版本使用用户输入的操作符代替等于操作。
find_first_of在指定范围内查找"由输入的另外一对iterator标志的第二个序列"中任意一个元素的第一次出现。重载版本中使用了用户自定义操作符。
find_if使用输入的函数代替等于操作符执行find
lower_bound返回一个ForwardIterator,指向在有序序列范围内的可以插入指定值而不破坏容器顺序的第一个位置。重载函数使用自定义比较操作。
upper_bound返回一个ForwardIterator,指向在有序序列范围内插入value而不破坏容器顺序的最后一个位置,该位置标志一个大于value的值。重载函数使用自定义比较操作
search给出两个范围,返回一个ForwardIterator,查找成功指向第一个范围内第一次出现子序列(第二个范围)的位置,查找失败指向last1。重载版本使用自定义的比较操作。
serach_n在指定范围内查找val出现n次的子序列。重载版本使用自定义的比较操作。
//查找算法

#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 

 
bool evenNum( int n ) //是否为偶数
{ return n % 2; }

bool sixNum( int n ) //是否等于5
{ return n == 5; }


int main()
 
{
 
    int num = 6;
    vector<int> v1;
    v1.push_back(3); 
    v1.push_back(3); 
    v1.push_back(3); 
    v1.push_back(3); 
    v1.push_back(3); 
    v1.push_back(4); 
    v1.push_back(5); 
    v1.push_back(6); 
    v1.push_back(7); 
    v1.push_back(8); 
    v1.push_back(9); 
    v1.push_back(10); 
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(6);


    //adjacent_find 查找相邻重复元素
    vector<int>:: iterator pos = adjacent_find(v1.begin(),v1.end());
    if(pos == v1.end()){
        cout << "未找到相邻重复元素" << endl;
    }else{
        cout << "找到相邻元素" << *pos << endl;
    }


    //binary_search
    if(binary_search(v1.begin(),v1.end(),4)){
        cout << "容器中含有元素4" << endl;
    }


    //equal_range 二分查找
    pair<vector<int>::iterator,vector<int>::iterator> range = equal_range(v1.begin(),v1.end(),3);
    cout << "这是一个啥东西" << *range.first << *range.second << endl;

    //lower_bound -函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置
    vector<int>:: iterator pos_lower = lower_bound(v1.begin(),v1.end(),3);
    cout << "大于等于3的第一个元素的位置" << *pos_lower << endl;


     //upper_bound - 函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置
    vector<int>:: iterator pos_upper = upper_bound(v1.begin(),v1.end(),3);
    cout << "大于3的第一个元素的位置" << *pos_upper << endl;


     
    //find
    vector<int>::iterator iter = find( v1.begin(), v1.end(), num ); //查找等于6的元素位置
    if( iter != v1.end() ){
        cout << "匹配元素的索引: " << iter - v1.begin() << endl; //找到匹配元素位置
    }
     
    vector<int> v2;
     
    v2.push_back(3);
    v2.push_back(4);
    v2.push_back(5);
    v2.push_back(6);
    //find_if
    iter = find_if(v2.begin(),v2.end(),sixNum);
    if(iter != v2.end()){
        cout << "等于5的元素索引是" << iter - v2.begin() << endl;
    }
     
    //find_first_of
    iter = find_first_of( v1.begin(), v1.end(), v2.begin(), v2.end() ); 
     
    if( iter != v2.end() ){
        cout << "第一个匹配元素索引:" << iter - v1.begin() << endl;
    }

    //find_end
    iter = find_end( v1.begin(), v1.end(), v2.begin(), v2.end() ); 
     
    if( iter != v2.end() ){
        cout << "最后一个匹配元素索引:" << iter - v1.begin() << endl;
    }
     
    //count_if
    int even_times = count_if( v1.begin(), v1.end(), evenNum ); 
    cout << "偶数个数 :" << even_times << endl;

    //count
    int four_times = count(v1.begin(), v1.end(), 4);
    cout << "元素4的个数 :" << four_times << endl;

 
    //search - 在一个序列中搜索与另一序列匹配的子序列。
    vector<int>:: iterator iterlocation = search(v1.begin(),v1.end(),v2.begin(),v2.end());
    if (iterlocation != v1.end())
    {
        cout << "v2的元素包含在v1容器中,起始元素为"
             << "v1[" << iterlocation - v1.begin() << "]" <<endl;
    } 
    else
    {
        cout << "v2的元素不包含在v1容器" << endl;
    }

    //search_n
    vector<int>:: iterator iterlocation_n = search_n(v1.begin(),v1.end(),3,3);
    if (iterlocation_n != v1.end())
    {
        cout << "在v1中找到3个连续的元素3" << endl;
    }
    else
    {
        cout << "在v1中没有3个连续的元素3" << endl;
    }




    
    
    return 0;
 
}

在这里插入图片描述

排序和通用算法 - 提供元素排序策略

方法含义
inplace_merge合并两个有序序列,结果序列覆盖两端范围。重载版本使用输入的操作进行排序
merge合并两个有序序列,存放到另一个序列。重载版本使用自定义的比较。
nth_element将范围内的序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面。重载版本使用自定义的比较操作。
partial_sort对序列做部分排序,被排序元素个数正好可以被放到范围内。重载版本使用自定义的比较操作。
partial_sort_copy与partial_sor类似,不过将经过排列的序列复制到另一个容器
partition对指定范围内元素重新排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前。
random_shuffle对指定范围内的元素随机调整次序。重载版本输入一个随机数产生操作
reverse将指定范围内元素重新反序排序。
reverse_copy与reverse类似,不过将结果写入另一个容器。
rotate将指定范围内元素移到容器末尾,由middle指向的元素成为容器第一个元素。
rotate_copy与rotate类似,不过将结果写入另一个容器。
sort以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。
stable_sort与sort类似,不过保留相等元素之间的顺序关系。
stable_partition与partition类似,不过不保证保留容器中的相对顺序。
//排序算法

#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 

bool cmp(int a,int b){
    return a>b;
}

bool tmp(int a){
    return a > 5;
}

void pprint(int t){
    printf("%d ",t);    
}

void merge_sort(vector<int>& nums, int l, int r)
{
    if(l<r)
    {
        int mid = (l+r)/2;
        merge_sort(nums, l, mid);
        merge_sort(nums, mid+1, r);
        inplace_merge(nums.begin()+l, nums.begin()+mid+1, nums.begin()+r+1);    
    }
}
 
int main()
 
{
 

    vector<int> v1;
    v1.push_back(1);
    v1.push_back(5);
    v1.push_back(6);
    v1.push_back(10);
    v1.push_back(20);

    vector<int> v2;
    v2.push_back(2);
    v2.push_back(3);
    v2.push_back(6);
    v2.push_back(15);
    v2.push_back(25);
    
    vector<int> v3(10);
  

     //使用for_each遍历
    cout << "v1的数据 :";
    for_each(v1.begin(),v1.end(),pprint);
    cout << endl;
    cout << "v2的数据 :" ;
    for_each(v2.begin(),v2.end(),pprint);
    //merge - 异地归并
    merge(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
    cout << endl;
    cout << "v3的数据 :";
    for_each(v3.begin(),v3.end(),pprint);
    cout << endl;

    //inplace_merge - 原地归并
    vector<int> v4;
    v4.push_back(20);
    v4.push_back(3);
    v4.push_back(60);
    v4.push_back(15);
    v4.push_back(25);
    merge_sort(v4, 0, v4.size()-1);
    cout << "v4的数据 :";
    for_each(v4.begin(),v4.end(),pprint);
    cout << endl;

    //sort,如果cmp缺省则为升序排列
    vector<int> v5;
    v5.push_back(203);
    v5.push_back(3);
    v5.push_back(60);
    v5.push_back(15);
    v5.push_back(25);
    v5.push_back(1);
    v5.push_back(5);
    v5.push_back(23);

    sort(v5.begin(),v5.end(),cmp);
    cout << "v5的数据 :";
    for_each(v5.begin(),v5.end(),pprint);
    cout << endl;


    //partition,把结果为true的元素放在结果为false的元素之前
    vector<int> v6;
    v6.push_back(2);
    v6.push_back(3);
    v6.push_back(60);
    v6.push_back(15);
    v6.push_back(25);
    v6.push_back(1);
    v6.push_back(5);
    v6.push_back(23);
    partition(v6.begin(),v6.end(),tmp);
    cout << "v6的数据 :";
    for_each(v6.begin(),v6.end(),pprint);
    cout << endl;


    //反转
    reverse(v5.begin(),v5.end());
    cout << "反转后v5的数据 :";
    for_each(v5.begin(),v5.end(),pprint);
    cout << endl;

    //旋转
    rotate(v5.begin(),v5.begin()+5,v5.end());
    cout << "旋转后v5的数据 :";
    for_each(v5.begin(),v5.end(),pprint);
    cout << endl;


    vector<int> v7;
    v7.push_back(2);
    v7.push_back(3);
    v7.push_back(60);
    v7.push_back(15);
    v7.push_back(25);
    v7.push_back(1);
    v7.push_back(5);
    v7.push_back(23);
    //局部排序
    partial_sort(v7.begin(),v7.begin()+5,v7.end());
    cout << "局部排序后v7的数据 :";
    for_each(v7.begin(),v7.end(),pprint);
    cout << endl;


    vector<int> v8;
    v8.push_back(2);
    v8.push_back(3);
    v8.push_back(60);
    v8.push_back(15);
    v8.push_back(10);
    v8.push_back(1);
    v8.push_back(5);
    v8.push_back(23);
    //数据分界
    //里面有四个参数,分别是起始位置,排序位置,结束位置,排序规则(没有按默认排序),起始和结束都很好理解,那排序位置就是第i个位置的前面都小于a[i],后面都大于a[i],但不保证前后的数字是有序的
    nth_element(v8.begin(),v8.begin()+5,v8.end(),cmp);
    cout << "数据分界后v8的数据 :";
    for_each(v8.begin(),v8.end(),pprint);
    cout << endl;
    
    
    return 0;
 
}

在这里插入图片描述

删除和替换算法

方法含义
copy复制序列
copy_backward与copy相同,不过元素是以相反顺序被拷贝
iter_swap交换两个ForwardIterator的值
remove删除指定范围内所有等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用remove和remove_if函数。
remove_copy将所有不匹配元素复制到一个制定容器,返回OutputIterator指向被拷贝的末元素的下一个位置。
remove_if删除指定范围内输入操作结果为true的所有元素
remove_copy_if将所有不匹配元素拷贝到一个指定容器
replace将指定范围内所有等于vold的元素都用vnew代替
replace_copy与replace类似,不过将结果写入另一个容器
replace_if将指定范围内所有操作结果为true的元素用新值代替
replace_copy_if与replace_if类似,不过将结果写入另外一个容器中
swap交换存储在两个对象中的值
swap_range将制定范围内的元素与另一个序列元素值进行交换
unique清除序列中重复元素,和remove类似,它也不能真正删除元素,重载版本使用自定义比较操作
unique_copy与unique类似,不过把结果输出到另一个容器
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 
 
bool evenNum( int n ) //是否为偶数
{ return n % 2 == 0; }

bool cmp(int a,int b){
    return a<b;
}

void pprint(int t){
    printf("%d ",t);    
}
 
int main()
 
{
 
    vector<int> v1;
    v1.push_back(0);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(1);
    v1.push_back(5);
    v1.push_back(4);
    v1.push_back(7);

    cout << "初始v1的数据 :";
    for_each(v1.begin(),v1.end(),pprint);
    cout << endl;


    vector<int> v2(v1.size());
    copy(v1.begin(),v1.end(),v2.begin());
    cout << "复制后v2的数据 :";
    for_each(v2.begin(),v2.end(),pprint);
    cout << endl;

    vector<int> v3(v1.size());
    copy_backward(v1.begin(),v1.end(),v3.begin());
    cout << "反向复制后v3的数据 :";
    for_each(v3.begin(),v3.end(),pprint);
    cout << endl;

    copy_backward(v1.end()-2,v1.end(),v1.end()-3);
    cout << "反向复制后v1的数据 :";
    for_each(v1.begin(),v1.end(),pprint);
    cout << endl;


    vector<int> v4;
    v4.push_back(0);
    v4.push_back(2);
    v4.push_back(3);
    v4.push_back(1);
    v4.push_back(5);
    v4.push_back(4);
    v4.push_back(6);
    remove(v4.begin(),v4.end(),1);
    cout << "删除v4中的1后的数据 :";
    for_each(v4.begin(),v4.end(),pprint);
    cout << endl;

    remove_if(v4.begin(),v4.end(),evenNum);
    cout << "删除v4中的偶数的数据 :";
    for_each(v4.begin(),v4.end(),pprint);
    cout << endl;


    vector<int> v5;
    v5.push_back(0);
    v5.push_back(2);
    v5.push_back(0);
    replace(v5.begin(),v5.end(),0,10);
    cout << "代替v5中的的数据 :";
    for_each(v5.begin(),v5.end(),pprint);
    cout << endl;

    //unique - 将后面不重复的元素覆盖前面重复的元素
    vector<int> v6;
    v6.push_back(1);
    v6.push_back(2);
    v6.push_back(2);
    v6.push_back(2);
    v6.push_back(1);
    v6.erase(unique(v6.begin(),v6.end()),v6.end());
    cout << "删除v6中的重复数据 :";
    for_each(v6.begin(),v6.end(),pprint);
    cout << endl;

    int a = 10;
    int b = 100;
    cout << "交换前" << "a:" << a << "b:" << b << endl;
    swap(a,b);
    cout << "交换后" << "a:" << a << "b:" << b << endl;
    
    return 0;
 
}

在这里插入图片描述

排列组合算法 - 提供计算给定集合按一定顺序的所有可能排列组合

方法含义
next_permutation取出当前范围内的排列,并重新排列为下一个排列。重载版本使用自定义的比较操作
prev_permutation取出指定范围内的序列并将它重新排列为上一个序列,如果不存在上一个序列则返回false,重载版本使用自定义的比较操作
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 
void pprint(int t){
    printf("%d ",t);    
}


 
int main()
 
{
 


    vector<int> v1;
     
    v1.push_back(3);
    v1.push_back(2);
    v1.push_back(4);
    v1.push_back(1);
    //降序排列
    printf("按降序排序过程\n");
    do{
        for_each(v1.begin(),v1.end(),pprint);
        printf("\n");
    }while(next_permutation(v1.begin(),v1.end()));

    vector<int> v2;
     
    v2.push_back(5);
    v2.push_back(10);
    v2.push_back(4);
    v2.push_back(20);
    //升序排列
    printf("按升序排序过程\n");
    do{
        for_each(v2.begin(),v2.end(),pprint);
        printf("\n");
    }while(prev_permutation(v2.begin(),v2.end()));
    return 0;
 
}

在这里插入图片描述

算术算法

方法含义
accumulateiterator对标识的序列段元素之和,加到一个由val制定的初始值上,重载版本不在做加法,而是传进来的二元操作符被应用到元素上
partical_sum创建一个新序列,其中每个元素值代表指定范围内该位置前所有元素之和。重载版本使用自定义操作代替加法。
insert_product对两个序列做内积(对应元素相乘,再求和)并将内积加到一个输入的初始值上。重载版本使用用户定义的操作。
adjacent_difference创建一个新序列,新序列中每个新值代表当前元素与上一个元素的差。重载版本用指定二元操作计算相邻元素的差。
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <numeric>

using namespace std;
 
 
bool evenNum( int n ) //是否为偶数
{ return n % 2; }

bool cmp(int a,int b){
    return a<b;
}

void pprint(int t){
    printf("%d ",t);    
}
 
int main()
 
{
 
    vector<int> v1;
    v1.push_back(9);
    v1.push_back(10);
    v1.push_back(100);
    v1.push_back(3);
    v1.push_back(20);
    v1.push_back(67);

    int sum1 = accumulate(v1.begin(),v1.end(),0);
    cout << "v1内的所有数据和" << sum1 << endl;


    
    return 0;
 
}

在这里插入图片描述

生成和异变算法

方法含义
fill将输入值赋给标志范围内的所有元素。
fill_n将输入值赋给first到first+n范围内的所有元素。
for_each用指定函数依次对指定范围内所有元素进行迭代访问,返回所指定的函数类型。该函数不得修改序列中的元素
generate连续调用输入的函数来填充指定的范围。
generate_n与generate函数类似,填充从指定iterator开始的n个元素。
transform将输入的操作作用与指定范围内的每个元素,并产生一个新的序列。重载版本将操作作用在一对元素上,另外一个元素来自输入的另外一个序列。结果输出到指定容器。
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 
 
int randoms(){
    return rand()%10;
}

void pprint(int t){
    printf("%d ",t);    
}
 
int main()
 
{
 
    vector<int> v1;
    v1.push_back(9);
    v1.push_back(10);
    v1.push_back(100);
    v1.push_back(3);
    v1.push_back(20);
    v1.push_back(67);

    fill(v1.begin()+1,v1.begin()+3,0);
    cout << "替代v1内的数据";
    for_each(v1.begin(),v1.end(),pprint);
    cout << endl;


    vector<int> v2;
    v2.push_back(12);
    v2.push_back(1);
    v2.push_back(3);
    v2.push_back(20);
    v2.push_back(6);
    fill_n(v2.begin()+1,3,9);
    cout << "从第二个位置开始替换3个9后v2内的数据";
    for_each(v2.begin(),v2.end(),pprint);
    cout << endl;


    vector<int> v3(5);
    generate(v3.begin(),v3.end(),randoms);
    cout << "随机生成v3内的数据";
    for_each(v3.begin(),v3.end(),pprint);
    cout << endl;

    vector<int> v4(10);
    generate_n(v4.begin()+3,4,randoms);
    cout << "从第四个位置随机生成4个数据后v4:";
    for_each(v4.begin(),v4.end(),pprint);
    cout << endl;

    transform(v4.begin(),v4.end(),v4.begin(),negate<int>());
    cout << "v4数据取反:";
    for_each(v4.begin(),v4.end(),pprint);
    cout << endl;
     

    
    return 0;
 
}

在这里插入图片描述

关系算法

方法含义
equal如果两个序列在标志范围内元素都相等,返回true。重载版本使用输入的操作符代替默认的等于操作符。
includes判断第一个指定范围内的所有元素是否都被第二个范围包含,使用底层元素的<操作符,成功返回true。重载版本使用用户输入的函数。
lexicographical_compare比较两个序列。重载版本使用用户自定义比较操作。
max返回两个元素中较大一个。重载版本使用自定义比较操作。
max_element返回一个ForwardIterator,指出序列中最大的元素。重载版本使用自定义比较操作。
min返回两个元素中较小一个。重载版本使用自定义比较操作。
min_element返回一个ForwardIterator,指出序列中最小的元素。重载版本使用自定义比较操作。
mismatch并行比较两个序列,指出第一个不匹配的位置,返回一对iterator,标志第一个不匹配元素位置。如果都匹配,返回每个容器的last。重载版本使用自定义的比较操作。
#include <vector>
#include <algorithm>
#include <iostream>
#include <functional>

using namespace std;
 
 
void pprint(int t){
    printf("%d ",t);    
}
 
int main()
{
  
  vector<int> v1;
  v1.push_back(1);
  v1.push_back(2);
  v1.push_back(3);
  v1.push_back(1);
  v1.push_back(4);
  v1.push_back(5);


  vector<int> v2;
  v2.push_back(1);
  v2.push_back(2);
  v2.push_back(3);
  v2.push_back(4);
  v2.push_back(5);


  bool rtn1 = equal(v1.begin(),v1.end(),v2.begin());
  if(rtn1){
    cout << "两个元素相等" << endl;
  }else{
    cout << "两个元素不相等" << endl;
  }

  bool rtn2 = includes(v1.begin(),v1.end(),v2.begin(),v2.end());
   if(rtn2){
    cout << "v1包含v2" << endl;
  }else{
    cout << "v1不包含v2" << endl;
  }


  //求最大值
  int max_num = *max_element(v1.begin(),v1.end());
  cout << "最大值:" << max_num << endl;

   //求最小值
   int min_num = *min_element(v1.begin(),v1.end());
   cout << "最小值:" << min_num << endl;


    //返回较大值
    int ax = max(3,5);
    int bi = min(3,5);
    cout << "比较大的" << ax << endl;
    cout << "比较小的" << bi << endl;


   
 
}

在这里插入图片描述

集合算法

方法含义
set_union构造一个有序序列,包含两个序列中所有的不重复元素。重载版本使用自定义的比较操作。
set_intersection构造一个有序序列,其中元素在两个序列中都存在。重载版本使用自定义的比较操作。
set_difference构造一个有序序列,该序列仅保留第一个序列中存在的而第二个中不存在的元素。重载版本使用自定义的比较操作。
set_symmertric_difference构造一个有序序列,该序列取两个序列的对称差集(并集-交集)。
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 
 

bool cmp(int a,int b){
    return a<b;
}

void pprint(int t){
    printf("%d ",t);    
}
 
int main()
 
{
 
    vector<int> v1,v2,v3;
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(6);
    v1.push_back(8);


    v2.push_back(1);
    v2.push_back(2);
    v2.push_back(3);
    v2.push_back(7);
    v2.push_back(9);
    v2.push_back(10);

    //并集
    set_union(v1.begin(),v1.end(),v2.begin(),v2.end(), back_inserter(v3));
    cout << "两个容器相加的结果" ;
    for_each(v3.begin(),v3.end(),pprint);
    cout << endl;
    v3.clear();

    //交集
    set_intersection(v1.begin(), v1.end(),v2.begin(), v2.end(),back_inserter(v3));
    cout << "两个容器相乘的结果";
    for_each(v3.begin(),v3.end(),pprint);
    cout << endl;
    v3.clear();


    //差集
    set_difference(v1.begin(), v1.end(),v2.begin(), v2.end(),back_inserter(v3));
    cout << "两个容器相减的结果";
    for_each(v3.begin(),v3.end(),pprint);
    cout << endl;
    v3.clear();


    
    return 0;
 
}

在这里插入图片描述

堆算法

方法含义
make_heap把指定范围内的元素生成一个堆。重载版本使用自定义比较操作。
pop_heap并不真正把最大元素从堆中弹出,而是重新排序堆。它把first和last-1交换,然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本使用自定义的比较操作。
push_heap假设first到last-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把元素插入容器后。重载版本使用指定的比较操作。
sort_heap对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>

using namespace std;
 
 

void pprint(int t){
    printf("%d ",t);    
}
 
int main()
 
{
    vector<int> v1;
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(1);
    v1.push_back(3);
    v1.push_back(2);

    // generate heap in the range of v1
    make_heap(v1.begin(), v1.end());
    cout << "initial max value : " << v1.front() << endl;
    
 
    // pop max value
    pop_heap(v1.begin(), v1.end());
    cout << "after pop, the max vsalue : " << v1.front() << endl;
    
 
    // push a new value
    v1.push_back(6);
    push_heap(v1.begin(), v1.end());
    cout << "after push, the max value : " << v1.front() << endl;
   
 
    
    return 0;
 
}

在这里插入图片描述

4)仿函数(Function object)
5)迭代适配器(Adaptor)
6)空间配制器(allocator)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++之STL 的相关文章

  • 有没有办法使用基于范围的 for 循环迭代最多 N 个元素?

    有没有一种好的方法可以使用基于范围的容器来迭代容器中的最多 N 个元素for标准库中的循环和 或算法 这就是重点 我知道我可以使用 旧 for带条件循环 基本上 我正在寻找与此 Python 代码相对应的内容 for i in arr N
  • 如何将两个STL向量的元素相加?

    这个问题很愚蠢 但我需要以一种非常有效的方式来做 它将在我的代码中一遍又一遍地执行 我有一个返回向量的函数 我必须将返回的值逐个元素添加到另一个向量中 非常简单 vector
  • 对动态大小的对象进行排序

    Problem 假设我有一个包含一些数据的大字节数组 最多 4GB 这些字节对应于不同的对象 使得每个s字节 认为 s 最多 32 将构成单个对象 一个重要的事实是这个尺寸s对于所有对象都是相同的 不存储在对象本身中 并且在编译时不知道 目
  • std::find 的优点

    使用 C 11 有什么优势吗std find超过一个容器的find method 如果是std vector 其中没有find方法 确实std find使用一些智能算法或简单地迭代每个元素的天真的方法 如果是std map看来你需要传递一个
  • C++ 内联字符串流

    我想用std stringstream创建格式化字符串 但使用内联类 所以我没有stringstream局部变量到处乱飞 我的意思是这样的 include
  • 在带有或不带有命名空间的 中使用类型

    在 C 11 中 我可以选择是否要使用带或不带命名空间 std 中定义的类型 至少我的编译器 g 4 7 接受这两种变体 我的问题是 使用 cstdint 中的 typedef 的推荐方法是什么 有或没有命名空间 有什么优点或缺点 或者这只
  • 从函数返回 STL 向量 - 复制成本

    当您从函数返回 stl 向量时 vector
  • STL:为向量编写“where”运算符

    我需要根据几个布尔谓词找到向量中的索引 ex vector
  • 无法在向量向量上使用 emplace_back() 花括号初始化器

    这与我之前提出的有关使用的问题有些相关emplace back在对向量上 将一对插入到 std vector 时 emplace back 与 Push back https stackoverflow com questions 5390
  • std::unordered_set 迭代器遍历的复杂性

    我最近玩了一个std unordered set http en cppreference com w cpp container unordered set 我怀疑我的 STL 版本会跟踪某些 FILO 数据结构 看起来像列表 中的非空存
  • C++ 中的 Java HashSet 等效项

    我很好奇 C 中是否有类似于 Java HashSet 的东西 IE 一个快速查看的数据结构 因为我只会运行 contains e 在上面 同样 如果你能启发我如何做 contains 无论您提出什么数据结构 我都会非常感激 O 请不要发帖
  • “向量迭代器+偏移量超出范围”断言有用吗?

    这个完美的程序在 Visual Studio 2013 的调试模式下失败了 include
  • 使用 std::istream_iterator 限制 std::copy 的范围

    我构建了一个最小的工作示例来展示我在使用 STL 迭代器时遇到的问题 我在用着istream iterator读书floatss 或其他类型 来自 astd istream include
  • STL容器如何复制对象?

    我知道 STL 容器 比如vector添加对象时复制该对象 push back方法如下 void push back const T x 我很惊讶地发现它把该项目作为参考 我编写了一个示例程序来看看它是如何工作的 struct Foo Fo
  • 在 C++ 中将惰性生成器实现为forward_iterator

    MyGenerator 表示 可能 有限的整数序列 计算成本很高 所以我不想预先生成它们并将它们放入容器中 struct MyGenerator bool HasNext int Next 要打印全部 MyGenerator generat
  • 如何将 list 对象附加到另一个对象

    在 C 中 我有两个list
  • 为什么这个 C++ STL 分配器不分配?

    我正在尝试编写一个派生自的自定义 STL 分配器std allocator 但不知何故所有的电话allocate 去基础班 我已将范围缩小到以下代码 template
  • STL迭代器是否保证集合更改后的有效性?

    假设我有某种集合 并且我在它的开头获得了一个迭代器 现在假设我修改了该集合 无论集合或迭代器的类型如何 我仍然可以安全地使用迭代器吗 为了避免混淆 以下是我讨论的操作顺序 获取集合的迭代器 修改集合 显然 不是其中的元素 而是集合本身 使用
  • 引用计数指针的STL类?

    这应该是微不足道的 但我似乎找不到它 除非不存在这样的类 智能指针的 STL 类 或类集 是什么 UPDATE 感谢您的回复 我必须说我很惊讶没有标准实施 我最终使用了这个 http archive gamedev net referenc
  • 如何修复 STL 样式容器以容纳不完整或抽象类型?

    几天前 我尝试以与 STL 容器相同的风格编写一个基本的树实现 现在我尝试在我的代码中使用它 但是有两件事似乎不起作用 但可以说std vector 即 使用不完整类型和使用抽象类型 如何修复我的树实现以获得此功能 我尝试稍微压缩一下我的代

随机推荐

  • 串口通信协议介绍

    串口通信协议介绍 空闲时 xff1a TX RX为高电平 xff0c 通讯时 xff1a 低电平为起始位 43 送数据位 xff08 从低到高 xff09 43 校验位 43 停止位 常用8N1 0 1 0 1 0 0 0 0 0 0 TX
  • ROS-基础(kinetic---melodic---noetic)

    学习资料参考 xff1a ROS机器人开发实践 胡春旭 目录 工作空间和功能包的创建集成开发环境的搭建话题和服务的实现方法ROS中的命名空间及解析方法ROS分布式通信的方法 热身 常用命令 命令作用catkin create pkg创建功能
  • linux下用多线程实现socket服务器和客户端的异步通信

    前面介绍了用select函数来实现socket的异步收发数据 xff0c 但是select函数也有一些缺陷 xff0c 要使socket能持续地通信 xff0c select必须不停地检测 xff0c 这样进程就会一直阻塞在这里 xff0c
  • SDN之NETCONF Call Home

    本文主要内容都来自于今年二月发布的RFC8071 NETCONF Call Home and RESTCONF Call Home xff0c 该RFC从2015年4月提出到最终发布一共修改了17个版本 xff0c 其间修改内容可以点击查看
  • Command ‘roscore‘ not found, but can be installed with: sudo apt install python-roslaunch

    Command roscore not found but can be installed with sudo apt install python roslaunch roscore 报错 Command 39 roscore 39 n
  • 按键精灵通过抓抓工具来获取坐标位置

    1 按键精灵通过抓抓工具找图 这里我就随便拿一款游戏来测试了 这是一款手游打开之后的界面 xff0c 要求我们点击确定继续现在要求使用脚本在帮我们点击这个确定按钮 我们新建一个脚本 然后打开按键精灵的抓抓工具 然后返回到按键精灵 xff0c
  • 在云服务器上部署项目(上)

    1 购买腾讯云主机 首先我们先了解一下云服务器的概念 云服务器 xff1a 高性能高稳定的云虚拟机 xff0c 可在云中提供弹性可调节的计算容量 xff0c 不让计算能束缚您的想象 xff1b 您可以轻松购买自定义配置的机型 xff0c 在
  • 在云服务器上部署项目(下)

    云服务器上部署项目 xff08 上 xff09 xff1a http blog csdn net gfd54gd5f46 article details 54331207 5 从网上下载jpress开源项目 流程 xff1a 下载jpres
  • 利用String类制作简单的网络爬虫

    网络爬虫 网络爬虫 xff08 又被称为网页蜘蛛 xff0c 网络机器人 xff0c 在FOAF社区中间 xff0c 更经常的称为网页追逐者 xff09 xff0c 是一种按照一定的规则 xff0c 自动地抓取万维网信息的程序或者脚本 另外
  • 令人头大的单片机延时----这里转一篇关于延时函数的文章看看

    标题 xff1a 转 关于nop 函数 2011 02 11 23 49 29 nop函数可以用来延时 xff0c 请问1个NOP延时多少时间 xff0c 怎么计算 xff1f 附一段说明 xff1a void nop void A NOP
  • Java----File类详解

    File类 Java中所有的目录都被当成File 对待 xff0c 它直接处理文件和文件系统 也就是说 xff0c File类没有指定信息怎样从文件读取或向文件存储 xff1b 它描述了文件本身的属性 File对象用来获取或处理与磁盘文件相
  • UEditor在JavaWeb中的应用

    富文本编辑器 xff08 UEditor xff09 在平时开发Java Web项目的时候 xff0c 往往会使用第三方插件来帮助我们更快的实现功能 这里教大家使用百度开源的富文本编辑器 xff08 UEditor xff09 来帮助我们更
  • DataTables入门

    DataTable是什么 xff1f Datatables是一款jquery表格插件 它是一个高度灵活的工具 xff0c 可以将任何HTML表格添加高级的交互功能 分页 xff0c 即时搜索和排序几乎支持任何数据源 xff1a DOM xf
  • Redis-cli客户端的使用

    启动Redis客户端 进入src目录启动Redis客户端 xff08 前提是先启动Redis Server xff09 redis span class hljs keyword cli span 测试存储数据 span class hlj
  • Node.js简介

    Node js概述 Node js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 Node js 使用了一个事件驱动 非阻塞式 I O 的模型 xff0c 使其轻量又高效Node js 的包管理器 npm xff0
  • 安装Node.js

    Node js安装包及源码下载地址为 xff1a https nodejs org en download Node js 历史版本下载地址 xff1a https nodejs org dist Window 上安装Node js 32
  • 使用Node.js快速创建web服务

    步骤一 引入 required 模块 span class hljs keyword var span http 61 span class hljs built in require span span class hljs string
  • okhttpUtil信任所有证书

    使用okhttp调用https信任所有证书工具类 请求示例 xff1a 结果 xff1a Caused by span class token operator span javax span class token punctuation
  • 从实际性能剖析,为什么MEMS激光雷达才是未来主流?

    车规级激光雷达的技术路线之争 xff0c 似乎已经逐渐明朗 高工智能汽车 注意到 xff0c 目前 xff0c 包括Innoviz以及国内一径科技 速腾聚创等越来越多的厂商先后推出了车规级MEMS激光雷达 另外 xff0c 需要特别注意的是
  • C++之STL

    定义 STL xff08 Standard Template Library xff09 xff0c 即标准模板库 xff0c 是一个具有工业强度的 xff0c 高效的C 43 43 程序库 它被容纳于C 43 43 标准程序库 xff08