首页 > 其他分享 >STL学习

STL学习

时间:2024-04-14 16:44:52浏览次数:24  
标签:返回 insert set STL 元素 学习 push include

栈:

stack容器内元素的访问
​由于栈(stack)本身就是一种后进先出的数据结构。在STL中stack中只能通过top()来访问栈顶元素

栈上的基本操作
栈的基本操作包括:

函数名 用途
push(x) 将x入栈
top() 获得栈顶元素
pop() 用以弹出栈顶元素
empty() 可以检测stack内是否为空,返回true为空,返回false为非空
size() 返回stack内元素的个数


队列:

队列遵循先进先出,后进后出,使用上和栈stack类似

队列函数调用

函数名 使用介绍
q.pop() 删除queue的队头元素
q.front() 返回队列的队头元素,但不删除该元素
q.back() 返回队列的队尾元素,但不删除该元素
q.push(arg) 将元素arg插入到队列的队尾
q.emplace(arg) 将元素arg放置到队列的尾部,作用和push一样
q.size() 返回队列中元素的个数
q.empty() 当队列为空时返回true,否则返回false
q.swap(q1) 交换q和q1中的元素,方法和stack中一样,并不会真正使用拷贝形式进行交换,只是交换底层的数据结构
swap(q,q1) 非成员函数,和成员函数swap一样


set:

set 的含义是集合,它是一个有序的容器,里面的元素都是排序好的,支持插入,删除,查找等操作,就像一个集合一样。所有的操作的都是严格在logn时间之内完成,效率非常高。set 和 multiset 的区别是:set 插入的元素不能相同,但是 multiset 可以相同。其特点如下:

  1. 每个元素的键值都唯一,不允许两个元素有相同的键值。
  2. 所有元素都会根据元素的键值自动排序(默认从小到大)。
  3. set 中的元素不像 map 那样可以同时拥有实值(value)和键值(key),只能存储键,是单纯的键的集合。
  4. set 中元素的值不能直接被改变。
  5. set 支持大部分的map的操作,但是 set 不支持下标的操作,而且没有定义mapped_type类型。

set基本操作

1、set 的定义及初始化

set<Type> s						      //定义一个set容器
set<Type> s(s1)			              //定义一个set容器,并用容器s1来初始化
set<Type> s(b, e)					  //b和e分别为迭代器的开始和结束的标记
set<Type> s(s1.begin(), s1.begin()+3) //用容器s1的第0个到第2个值初始化s
set<Type> s(a, a + 5)      		      //将a数组的元素初始化vec向量,不包括a[4]
set<Type> s(&a[1], &a[4]) 			  //将a[1]~a[4]范围内的元素作为s的初始值

set 的基本操作

s.begin()					//返回指向第一个元素的迭代器
s.end()						//返回指向最后一个元素的迭代器
s.clear()					//清除所有元素
s.count()					//返回某个值元素的个数
s.empty()					//如果集合为空,返回true,否则返回false
s.equal_range()				//返回集合中与给定值相等的上下限的两个迭代器
s.erase()					//删除集合中的元素
s.find(k)					//返回一个指向被查找到元素的迭代器
s.insert()					//在集合中插入元素
s.lower_bound(k)			//返回一个迭代器,指向键值大于等于k的第一个元素
s.upper_bound(k)			//返回一个迭代器,指向键值大于k的第一个元素
s.max_size()				//返回集合能容纳的元素的最大限值
s.rbegin()					//返回指向集合中最后一个元素的反向迭代器
s.rend()					//返回指向集合中第一个元素的反向迭代器
s.size()					//集合中元素的数目

set用法:

基本用法

#include <iostream>
#include <set>
using namespace std;
int main(){
     set<int> s;
     s.insert(1);
     s.insert(2);
     s.insert(3);
     s.insert(1);
     cout<<"set的size值为 :"<<s.size()<<endl;
     cout<<"set的maxsize的值为 :"<<s.max_size()<<endl;
     cout<<"set中的第一个元素是 :"<<*s.begin()<<endl;
     s.clear();
     if(s.empty())
         cout<<"set为空"<<endl;
     cout<<"set的size值为 :"<<s.size()<<endl;
     cout<<"set的maxsize的值为 :"<<s.max_size()<<endl;
     return 0;
}

set.end()不是最后一个元素,它指向最后元素的后一位。
这样可以常用来遍历set。
实际上它效果上等同与set.size()
如果是{1, 55, 99999},那么set.size() == set.end() == 3

  1. 插入3之后虽然插入了一个1,但set中最后一个值仍然是3 。一共插入了4个数,但是集合中只有3个数并且是有序的,说明了set集合的两个特点,有序和不重复。
  2. begin() 和 end()函数是不检查set是否为空的,使用前最好使用empty()检验一下set是否为空。

count() 的用法

//返回某个值元素的个数
#include <iostream>
#include <set>
using namespace std;
int main(){
     set<int> s;
     s.insert(1);
     s.insert(2);
     s.insert(3);
     s.insert(1);
     cout<<"set 中 1 出现的次数是 :"<<s.count(1)<<endl;
     cout<<"set 中 4 出现的次数是 :"<<s.count(4)<<endl;
     return 0;
}

总结: count() 用来查找set中某个键值出现的次数,但因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了,所以这个函数在set中并不是很实用。

erase() 的用法

  1. erase(iterator) :删除定位器iterator指向的值

  2. erase(first,second):删除定位器first和second之间的值

  3. erase(key_value):删除键值key_value的值

#include <iostream>
#include <set>
using namespace std;
int main(){
     set<int> s;
     set<int>::const_iterator it;
     set<int>::iterator first;
     set<int>::iterator second;
     for(int i=1; i<=10; ++i)
         s.insert(i);
     //第一种删除,删掉1
     s.erase(s.begin());
     //第二种删除,删掉2和3
     first = s.begin();
     second = s.begin();
     second++;
     second++;
     s.erase(first,second);
     //第三种删除,删掉8
     s.erase(8);
     cout<<"删除后 set 中元素是 :";
     for(it=s.begin(); it!=s.end(); ++it)
         cout<<*it<<" ";
     cout<<endl;
     return 0;
}

总结: set中的删除操作是不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己一定要注意。

find() 的用法

//返回一个指向被查找到元素的迭代器,如果没找到则返回end()
#include <iostream>
#include <set>
using namespace std;
int main(){
     int a[] = {4,5,6};
     set<int> s(a,a+3);
     set<int>::iterator it;
     if((it=s.find(4))!=s.end())
         cout<<*it<<endl;
     return 0;
}

输出结果

4

insert() 的用法

  1. insert(key_value):将key_value插入到set中 ,返回值是pair<set: :iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置;若key_value已经在set中,则iterator表示的key_value在set中的位置。

  2. inset(first,second);将定位器first到second之间的元素插入到set中,返回值是void.

#include <iostream>
#include <set>
using namespace std;
int main(){
     int a[] = {1,2,3};
     set<int> s;
     set<int>::iterator it;
     s.insert(a,a+3);
     for(it=s.begin(); it!=s.end(); ++it)
         cout<<*it<<" ";
     cout<<endl;
     pair<set<int>::iterator,bool> pr;
     pr=s.insert(5);
     if(pr.second)
         cout<<*pr.first<<endl;
     cout<<"插入数值之后的set中有:"<<endl;
	 for(it=s.begin(); it!=s.end(); ++it)
		cout<<*it<<" ";
	 cout<<endl;
     return 0;
}

lower_bound()、upper_bound() 的用法

  1. lower_bound(key_value) :返回第一个大于等于key_value的定位器

  2. upper_bound(key_value):返回第一个大于key_value的定位器

#include <iostream>
#include <set>
using namespace std;
int main(){
     set<int> s;
     s.insert(1);
     s.insert(3);
     s.insert(4);
     s.insert(6);
     cout<<*s.lower_bound(1)<<endl;
     cout<<*s.lower_bound(2)<<endl;
     cout<<*s.upper_bound(3)<<endl;
     return 0;
}

输出结果:

1
3
4

equal_range() 的用法

equal_range():返回一对定位器,分别表示第一个大于等于给定关键值的元素和第一个大于给定关键值的元素,这个返回值是一个pair类型。如果这一对定位器中哪个返回失败,就会等于end()的值。

#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int main(){
	set<int> s;
	set<int>::iterator it;
	for(int i=1; i<=5; ++i)
		s.insert(i); //向set中加入数据
	for(it=s.begin(); it!=s.end(); ++it)
		cout<<*it<<" ";  //输出set中的数据
	cout<<endl;
	pair<set<int>::const_iterator,set<int>::const_iterator> pr;
	pr=s.equal_range(3);
	cout<<"第一个大于等于3的数是:"<<*pr.first<<endl;
	cout<<"第一个大于3的数是: "<<*pr.second<<endl;
	return 0;
}

自定义比较函数
(1). 元素不是结构体:

 //自定义比较函数myComp,重载“()”操作符
struct myComp{
	bool operator()(const your_type &a,const your_type &b){
		return a.data > b.data;
	}
}
set<int,myComp>s;
set<int,myComp>::iterator it;

(2). 元素是结构体:

//可以直接将比较函数写在结构体内
struct Info{
	string name;
	float score;
	//重载“<”操作符,自定义排序规则
	bool operator < (const Info &a) const{
		//按score从大到小排列
		return a.score<score;
	}
}
 
set<Info> s;
set<Info>::iterator it;


优先队列:

和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队

优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的

和队列基本操作相同:

· top 访问队头元素
· empty 队列是否为空
· size 返回队列内元素个数
· push 插入元素到队尾 (并排序)
· emplace 原地构造一个元素并插入队列
· pop 弹出队头元素
· swap 交换内容

定义:priority_queue<Type, Container, Functional>
Type 就是数据类型
Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector)
Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆

一般是:

//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;

//greater和less是std实现的两个仿函数
//(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)

基本类型例子:

#include<iostream>
#include <queue>
using namespace std;
int main() 
{
    //对于基础类型 默认是大顶堆
    priority_queue<int> a; 
    //等同于 priority_queue<int, vector<int>, less<int> > a;
    
  
    priority_queue<int, vector<int>, greater<int> > c;  //这样就是小顶堆
    priority_queue<string> b;

    for (int i = 0; i < 5; i++) 
    {
        a.push(i);
        c.push(i);
    }
    while (!a.empty()) 
    {
        cout << a.top() << ' ';
        a.pop();
    } 
    cout << endl;

    while (!c.empty()) 
    {
        cout << c.top() << ' ';
        c.pop();
    }
    cout << endl;

    b.push("abc");
    b.push("abcd");
    b.push("cbd");
    while (!b.empty()) 
    {
        cout << b.top() << ' ';
        b.pop();
    } 
    cout << endl;
    return 0;
}

输出:

4 3 2 1 0
0 1 2 3 4
cbd abcd abc

pari的比较,先比较第一个元素,第一个相等比较第二个

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main() 
{
    priority_queue<pair<int, int> > a;
    pair<int, int> b(1, 2);
    pair<int, int> c(1, 3);
    pair<int, int> d(2, 5);
    a.push(d);
    a.push(c);
    a.push(b);
    while (!a.empty()) 
    {
        cout << a.top().first << ' ' << a.top().second << '\n';
        a.pop();
    }
}

输出:

2 5
1 3
1 2

对于自定义类型

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

//方法1
struct tmp1 //运算符重载<
{
    int x;
    tmp1(int a) {x = a;}
    bool operator<(const tmp1& a) const
    {
        return x < a.x; //大顶堆
    }
};

//方法2
struct tmp2 //重写仿函数
{
    bool operator() (tmp1 a, tmp1 b) 
    {
        return a.x < b.x; //大顶堆
    }
};

int main() 
{
    tmp1 a(1);
    tmp1 b(2);
    tmp1 c(3);
    priority_queue<tmp1> d;
    d.push(b);
    d.push(c);
    d.push(a);
    while (!d.empty()) 
    {
        cout << d.top().x << '\n';
        d.pop();
    }
    cout << endl;

    priority_queue<tmp1, vector<tmp1>, tmp2> f;
    f.push(c);
    f.push(b);
    f.push(a);
    while (!f.empty()) 
    {
        cout << f.top().x << '\n';
        f.pop();
    }
}

输出:

3
2
1

3
2
1

标签:返回,insert,set,STL,元素,学习,push,include
From: https://www.cnblogs.com/miao-jc/p/18134207

相关文章

  • httprunner 4.x学习 - 04提取(extract)和校验(validate)
    前言支持2种响应结果字段提取方式:1.jmespath表达式:响应结果为JSON结构,采用jmespath表达式进行参数提取。参考教程https://jmespath.org/tutorial.html2.正则表达式(regex):返回的非JSON 格式,可以用正则表达式(regex)提取。需要具备一定的正则知识extract提取返......
  • [深度学习]模型选择、过拟合、欠拟合
    模型选择、过拟合、欠拟合在机器学习和统计建模中,模型选择、过拟合和欠拟合是常见的概念,关系到模型的性能和泛化能力。1.模型选择举个一个有趣的例子:惊讶的发现:你发现所有的5个人在面试的时候都穿了蓝色衬衫(就是咱们说的蓝领嘛)你的模型也发现了这个强信号这会有什么问......
  • STL笔记 之 vector
    初识STLSTL,(StandardTemplateLibrary),即"标准模板库",由惠普实验室开发,STL中提供了非常多对信息学奥赛很有用的东西。vectorvetor是STL中的一个容器,可以看作一个不定长的数组,其基本形式为:vector<数据类型>名字;如:vector<int>v或vector<char>t。vector的基本操作先定......
  • 凸包 学习笔记
    1前置知识1.1三角函数1.2向量四则运算2凸包2.1凸包定义2.2Graham扫描法2.3相关例题IFencingthecowsII信用卡凸包III防线修建......
  • 最近公共祖先 学习笔记
    概念一棵有根树,求两个点的最近公共祖先。方法1.倍增法:\(O(n)-O(\logn)\)intlca(intx,inty){ if(dep[x]<dep[y])swap(x,y); while(dep[x]>dep[y])x=fa[x][__lg(dep[x]-dep[y])-1]; if(x==y)returnx; for(intk=__lg(dep[x])-1;~k;k--) if(fa[x][k]!=fa[y][k]......
  • Splay 学习笔记
    为了LCT制造了一个Splay……Splay还是一种二叉排序树。我们想让他支持查询结点,删除结点等等。但是普通BST复杂度难以保证,于是Splay出现了。【引入】Splay的思想和并查集的路径压缩类似。并查集的路径压缩允许出现一两次复杂度高的操作,但是经历过一次后就不会再有第二......
  • 架构学习-多任务
    架构学习-多任务:进程,线程,协程多任务参考架构学习-多任务:进程,线程,协程多任务多任务处理:是指计算机同时运行多个程序的能力。比如说,我们在使用电脑的时候,可以边听音乐,边写文档。从物理层面上看,最早的CPU都是单核的,也就是同一时间只能执行一条指令。单核CPU是如何支......
  • Spring学习笔记
    一、Spring启示录阅读以下代码:packagecom.powernode.oa.controller;importcom.powernode.oa.service.UserService;importcom.powernode.oa.service.impl.UserServiceImpl;publicclassUserController{privateUserServiceuserService=newUserServiceImpl();......
  • 多项式学习笔记
    1.前置知识1.1基础\(f(x)=\sum_{i=0}^na_ix^i\)被称为一个\(n\)次多项式。\(\degf(x)\)表示多项式的次数。\(f(x)g(x)=h(x)\)称为多项式乘法,也叫多项式卷积,满足\(h_n=\sum_{i+j=n}f_ig_j\)。1.2点值给定一个多项式\(f(x)\),再给\(m\)个点\(x_1,\dot......
  • [深度学习]多层感知机(MLP)
    多层感知机(MLP)1.单层感知机1.1感知机线性回归输出的是一个实数,感知机输出的是一个离散的类。1.2训练感知机①如果分类正确的话y<w,x>为正数,负号后变为一个正数,和\(0\)取\(max\)之后得\(0\),则梯度不进行更新②如果分类错了,y<w,x>为负数,的判断条件成立,就进行梯度更新。......