STL——容器与算法详解(10分钟快速入门)

STL与algorithm头文件

STL是一些容器的集合,这些容器有list,vector,set,map等

algorithm是对容器继承的一些算法函数,辅助刷算法题

如sort()排序函数以迭代器(指针也可以)为参数

1.string字符串

1.1+=运算符

string头文件中把+=重载了,可以接受的参数为,字符串,字符,ASCII码

大小写ASCII码,A65,a97,之间间隔32

###1.2sort()中对其的应用

string s="123";
sort(s.begin(),s.end());

输出123

1.3erase方法

例如删除字符串中第一个字符和最后一个字符

string s="123";
s.erase(s.begin());
s.erase(--s.end());

begin()是头迭代器,end()是尾迭代器

1.4substr方法

string s="5418340";
string s1=s.substr(1,3);//取418,取索引为1,往后截断3个
string s2=s.substr(1,-1);//索引为1,截断到最后

1.5循环方式

1.5.1for循环

for(int i=0;i<s.length();i++)//s.length()返回字符串长度

1.5.2利用迭代器循环

string s="123";
//常规写法
for(string::iterator<string> it=s.begin();it!=s.end();it++)
    cout<<*it;

1.5.3迭代器简化版auto

string s="123";

//简便写法,采用auto
for(auto it=s.begin();it!=s.end();it++)
    cout<<*it;//取出来的是char类型

1.5.4C++11新特性

string s="123";

//C++11新特性,s需要是一个可遍历的容器或流,x用来在遍历过程中获得容器的每一个元素,相当于java中的for each
for(auto x:s)
    cout<<x;

2.vector向量

2.1vector基础

vector<int> v;//定义空向量
for(auto x:v) cout<<x;//输出NULL,空

vector<int> v2(4);
for(auto x:v2) cout<<x;//输出4个0

vector<int> v3(4,6);
for(auto x:v3) cout<<x;//输出4个6

//也可以使用大括号定义
vector<int> v{1,2,3,4,5,6};

//获取元素方式
cout<<v[0];
cout<<v.at(0);//两种方式等价

//循环
for(int i=0;i<v.size();i++);
for(vector<int>::iterator it=v.begin();it<v.end();it++);
for(auto it = v.begin();it<v.end();it++);
for(auto x:v) cout<<x;

2.2方法

v.push_back(5);//追加内容,int型5
v.resize(10);//调整大小,多出来的默认为0
v.erase(v.begin());//删除元素,复杂度为O(n)

//获取第一个元素
v.front();
v[0];
*v.begin();

//获取最后一个元素
v.back();
v[v.size()-1];//size方法获取向量大小
*(--v.end());

2.3排序

vector<int> v{5,1,2,5,4,0,-1};

sort(v.begin(),v.end());//默认从小到大排序
sort(v.begin(),v.end(),less<int>())//带比较器从小到大排序

sort(v.begin(),v.end(),greater<int>());//带比较器从大到小排序

3.stack栈

3.1stack基础

#include<stack>
//构造方法,一般使用空参构造
stack<int> s;

3.2方法

push、pop、size、empty

  • pop没有返回值
  • size返回栈中数目
s.push(2);//压栈
int num = s.top();//取栈顶元素
s.pop();
s.size();

3.3应用

3.3.1进制转换

//把10进制转换为2进制
int itob(int decimal)
{
    int ans=0;
    stack<int> s;
    while(decimal!=0)
    {
        s.push(decimal%2);
        decimal/=2;
    }
    while(!s.empty())
    {
        ans=ans*10+s.top();
        s.pop();
    }
    return res;
}
//input 20 
//output 10100

3.3.2逆序单词(拓展sstream,stoi,itoa)

输入一行字符串,将字符串逆序打出

hello world

//方法1,采用流,sstream
#include <sstream>
int main()
{
    string str;
	getline(cin,str);
	stringstream ss;
	ss<<str;//str内容流入ss流对象中
	while(ss>>str)
	{
    	cout<<str;
	}
	return 0;
}


//方法2,采用stack
int main()
{
    string str;
    stack<string> s;
	getline(cin,str);
	stringstream ss;
	ss<<str;//str内容流入ss流对象中
	while(ss>>str)
    	s.push(str);
	
    while(!s.empty())
    {
        cout<<s.top();
        s.pop()
        //oj不允许最后一行为换行符
        if(s.size()!=1) cout<<" ";
    }
    
	return 0;
}
//输出为 world hello

3.3.3 字符串转数字

//方法1,sstream,利用流和cout对象自身对输入的转换
#include <sstream>
int main()
{
    string s="1234";
    int i;
    stringstream ss;
    ss<<s;
    ss>>i;
    cout<<i;
    return 0;
}

//方法2,string中的函数stoi()
#include <string>
int main()
{
    string s="1234";
    int i = stoi(s);
    cout<<i;
    return 0;
}

3.3.4数字转字符串

//方法1,sstream,利用流和cout对象自身对输入的转换
#include <sstream>
int main()
{
    int a=1234;
    string out;
    stringstream ss;
    ss<<a;
    ss>>out;
    cout<<out<<endl;
    return 0;
}

//方法2,c++新特性,to_string()函数

int a=1234;
cout<<to_string(a)<<endl;

//方法3,itoa()将整型转为字符串
需要#include<cstdlib>

4.queue队列

4.1队列基本操作

#include<queue>
q.push(5);
q.push(6);
cout<<q.front()<<endl;
q.pop();
cout<<q.front()<<endl;
cout<<q.size()<<endl;

5.map&unordered_map映射

4.1map基本操作

概念:映射

map底层是树状结构;unordered_map底层是哈希结构

#include<map>

map<int,int> m;//map底层为有序的树状结构
m[6]=3;
m[5]=8;
m[4]=9;
for(auto it = m.brgin();it!=m.end();it++)
  cout<<it->first<<" "<<it->second<<endl;
//map输出4 9;5 8;6 3;说明map内部是按照first元素升序排序的
for(auto tmp:m)
    cout<<tmp.first<<" "<<tmp.second<<endl;
  

4.2unordered_map

#include<unordered_map>

unordered_map<int,int> m;//底层为无序的哈希结构,快很多
m[6]=3;
m[5]=8;
m[4]=9;
for(auto it = m.brgin();it!=m.end();it++)
  cout<<it->first<<" "<<it->second<<endl;
//输出4 9;5 8;6 3;内部有时候按照first元素升序排序的,有时候无序
for(auto tmp:m)
    cout<<tmp.first<<" "<<tmp.second<<endl;
  

4.3pair的用法

对map进行排序操作,map中元素是pair结构,pair是映射元素对结构

pair不需要加任何头文件, 因为其在在头文件utility里面定义。

#include<algorithm>
#include<iostream>
#include<map>
#include<unordered_map>
#include<vector>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b)
{
	return a.first < b.first;//升序排列
}

int main()
{
	unordered_map<int, int> m;//底层为无序的哈希结构,快很多
	m[6] = 3;
	m[5] = 8;
	m[4] = 9;

#if 0
	sort(m.begin(), m.end(), cmp);
	for (auto tmp : m)
		cout << tmp.first << " " << tmp.second << endl;
	//输出报错,说明其不可排序,需要把map转换为vector结构
#endif

	vector<pair<int, int>> v(m.begin(), m.end());
	//用m的迭代器初始化vector v
	sort(v.begin(),v.end(),cmp);
	for (auto tmp : v)
		cout << tmp.first << " " << tmp.second << endl;
}

6.set&unordered_set集合

6.1set基本使用

set是一个集合

#include<set>
#include<iostream>
using namespace std;
int main()
{
	set<int> s;
	s.insert(3);
	s.insert(4);
	s.insert(4);
	cout << s.size() << endl;
	for (auto tmp : s)
	{
		cout << tmp << " ";
	}
	cout << endl;
	for (auto it = s.begin(); it != s.end(); it++)
		cout << *it << " ";
	cout << endl;
	return 0;
}

set是树状结构,有序;unodered_set是哈希结构,无序,快

7.deque双端队列

deque是双端队列, 理解为即可以在前面也可以在后面操作的管子

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

int main()
{
	deque<int> d;
	d.push_back(1);
	d.push_back(2);
	cout << d.back() << endl//2
		<< d.front() << endl;//1

	d.push_front(9);
	d.push_front(4);
	//现在存的是4912
	d.pop_back();//2
	d.pop_front();//4
	for (auto tmp : d) cout << tmp << endl;
	for (auto it = d.begin(); it != d.end(); it++) cout << *it;
	return 0;
}

排序

#include<iostream>
#include<deque>
#include<algorithm>
using namespace std;

int main()
{
	deque<int> d;
	d.push_back(1);
	d.push_back(2);
	cout << d.back() << endl//2
		<< d.front() << endl;//1

	d.push_front(9);
	d.push_front(4);
	//现在存的是4912
	
	sort(d.begin(), d.end(), greater<int>());
    //greater<int>()从大到小排序

	for (auto tmp : d) cout << tmp <<" ";
	//for (auto it = d.begin(); it != d.end(); it++) cout << *it;
	return 0;
}

8.list双向链表

list是双向链表

list插入和删除都是O(1),查询是O(N),

使用方法

#include <iostream>
#include <list>
using namespace std;
int main()
{
    list<int> li;
    li.push_back(6);
    li.push_front(5);
    li.emplace_front(9);
    li.emplace_back(10);
    li.insert(++li.begin(),2);
    for(auto tmp:li) cout<<tmp<<endl;
    for(auto it = li.begin();it!=li.end();it++)
        cout<<*it<<endl;
    return 0;
}

9 不懂的地方查文档

英文文档

中文文档

发布了49 篇原创文章 · 获赞 29 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_41122796/article/details/104782535