acm中stl大总结(吐血总结)(更新中)

在打比赛的时候stl能帮助我们省下很多时间,减少很多麻烦,这么久也只是零零散散地用,有时忘了就百度,导致比赛的时候根本想不起来,还有很多的内容并不熟知,所以决定系统地总结学习一下来加深印象

首先举例说明最常用的(对我来说) 本篇文章会不断更新,添加用到的,好用的stl模板


  1. 万能头文件
    包含了我们需要的所有头文件
    不过唯一的缺点就是降低了编译的速度(不太懂…没学过编译原理)
    目前大部分主流oj都能使用(poj貌似不行)

  2. 先讲讲输入输出吧
    //虽然我们有万能头文件,但是我还是会依次列出各个头文件
    头文件< iostream >就包含了输入输出
    我习惯的常用的就是cin输入,cout输出(比printf和scanf要慢

	int a;
	cin>>a;
	cout<<a<<endl; //endl就是endline的简写,就是换行的意思

需要注意的是,cin读一个字符串的时候是不读空格,回车和换行的
如果你第一个输入的就是空格回车和换行那么cin是会自动忽略并等待输入的

如果要读空格可以用getline,具体使用看下面代码

	string str2;
	getline(cin,str2);
	cout<<str2<<endl;

当然了还可以用cin.get(str,size)来读一行,要注意的是str只能是char*的数组,然后size的话是你要输入的字符个数,会消耗一个用来存‘\0’
这种c style的东西用的也少

  1. stringstream 要使用的头文件是< sstream >
    我之前一直用的是字符串与数字的转换
    具体可以看下面的代码,用起来也很方便
	int n;string s="123546";  //字符串转数字
	stringstream ss(s);
	ss>>n; 
	cout<<n;
	int n=1234;string s;  //数字转字符串
	stringstream ss(s);
	ss<<n;
	ss>>s;
	cout<<s;

然后stringstream一个很大的用处就是去空格
再读字符串的时候会以空格进行分割,具体可以看下面代码

	string s="12 ab 34 cd 56";
	stringstream ss(s);
	while(ss>>s){//这里把s换成其它变量可能会更好理解
		cout<<s;   //当然也可以用字符数组来存储
						//	输出的是12ab34cd56
	}

stringstream不仅支持string类型的转化,同时还能对char* 进行输入输出

4.栈 stack 头文件< stack >
栈用的多也挺简单,简单列举一下
s.pop() 弹出栈顶元素
s.push()向栈中加入元素
s.size()栈的大小
s.empty()判断栈是否为空,空返回1,非空返回0
s.top()返回栈顶元素

	stack<int> s; //这里的int代码栈中元素的类型,当然可以替换为其它的任何类型,比如自己定于的结构体
	s.push(1);
	s.push(2);
	s.push(3);
	cout<<s.top()<<endl; //3
	s.pop();
	cout<<s.top()<<endl; //2
	cout<<s.size()<<endl;//2
	if(s.empty()){
		cout<<"kong"<<endl;
	} 
	else{
		cout<<"feikong"<<endl; 
	} 

5.string
字符串在很多比赛中很重要
先说说用的多的tolower与toupper,用来对字符串进行大小写的转化
这两个方法的返回值是int类型,所以不要直接输出,可以用一个字符串来存
具体用法可以直接看下面代码

string str="ICPC WORLD FINAL";
	for(int i=0;i<str.length();i++){
		str[i]=tolower(str[i]);//toupper就是转成大写
	}
	cout<<str<<endl; 

string的基本操作有
s.size()或者s.length()返回字符串的长度
s.empty()判断是否为空
s1+s2可以把两个字符串合并,append()方法可以在字符串后追加字符串

下面列举string字符串用的比较多的方法
isalnum ( c ) 如果c是字母或数字,返回 true
isalpha( c) 如果c是字母,返回true
iscntrl( c) c是控制符,返回true
isdigit( c) 如果c是数组,返回true
isgraph( c) 如果c不是空格,则可打印,,则为true
islower( c) 如果c是小写字母,则为true
isupper( c) 如果c是大写字符,则为true
isprint( c) 如果c是可打印的字符,则为true
ispunct( c) 如果c是标点符号,则为true
isspace( c) 如果c是空白字符,则为true
isxdigit( c) 如果c是十六进制数,则为true

然后是字符串中一些非常方便的操作

s.insert(i,str) 把str字符串插入到s字符串 i 的位置

s.replace(pos,length,str) 从pos位置开始,将后面的length个字符串替换为str
注意,如果length为0的话,效果就是insert的效果

s.earse(i,j) 把下标i到j的元素清除
要注意的是earse还是少用的好,容易出错。清除后其它元素下标是改变了的,有些地方说erase(i)是把下标为i的元素清除,但是亲测为把i以后的元素全部清除

s.find() 也是一个常用的方法 find方法有唯一的返回值那就是size_type ,如果查找成功,返回下标,查找失败返回npos,也就是-1,注意的是,npos打印时并不显示-1,而是一个无符号整数,但是你仍然可以用-1进行判断。

s.find(str) 在s中查找第一个str,可以是字符串也可以是字符
s.find(str,pos) 从pos下标开始查找str
s.rfind(str,pos)的话就是从pos下标开始向前查找 ,方向不同(包括pos)

下面一段代码举例说明

	string s="ICPC WORLD FINAL";
	string str="2019";
	s.append(str);
	cout<<s<<endl;   //输出是ICPC WORLD FINAL2019
	s.erase(s.length()-str.length(),s.length());
	cout<<s<<endl; //输出为 ICPC WORLD FINAL
	cout<< s.find('C');    // 1
	cout<<s.find('C');     //3

6.vector 头文件 < vector >
向量,可以看作是数组的加强版
申明vector 可以直接vector< int > v;
也可以直接用数组来初始化向量
int n[] = {1, 2, 3, 4, 5} ;
vector a(n, n+5) ; //将数组n的前5个元素作为向量a的初值

vector常用的操作有

v.size() 用于获取vector的长度
v.empty() 判断向量是否为空
v.clear() 清空
v.push_back() 向向量尾部插入数据
v.pop_back() 向量尾部删除数据
v.erase(v.begin(),v.begin()+3) ; 将(v.begin(), v.begin()+3)之间的元素删除
v.front() 为向量的第一个元素
v.back() 为向量的最后一个元素
v.begin() v.end() 的返回值是迭代器
vector中元素的翻转:reverse(vec.begin(),vec.end());

可以像数组一样地访问向量,当然也可以使用迭代器对stl进行遍历

for(vector<int>::iterator it=v.begin();it!=v.end();it++)
    cout<<*it<<endl;    

对于二维vector,申明方法如下

vector< vector<int> > b(10, vector< int >(5,0)); //创建一个10*5的int型二维向量b
  1. Queue 头文件< queue >
    封装好的队列,直接使用挺方便
    和其它容器定义方式类似
    queue< int >q ;
    queue和stack一样没有迭代器

基本操作与其它容器类似

q.pop() ; 出队
q.push(); 入队
q.size(); 长度
q.empty() ; 判断是否为空
q.front() q.back() 队首队尾元素

8.priority_queue 优先队列 同样在< queue > 头文件中
优先队列与普通队列的区别就在于 优先队列能自动排序

定义优先队列:
priority_queue pq1; // 元素从小到大输出
其中3个参数分别表示 成员类型int , 底层容器类型vector, 还有最后的比较函数
所以如果我们使用less 就是将元素从大到小出队

priority_queue 的操作有:
pq1.empty() 判断是否为空,若为空则返回1
pq1.pop() 删除第一个元素
pq1.push(1) 加入一个元素
pq1.size() 输出队列元素个数
pq1.top() 返回队列顶端元素,即优先度最高的元素

需要说明的是在定义优先队列的时候,最后两个< 不要放到一起,不然会被误认为<< 而报错

当然了,最后的比较函数我们可以自己定义,我们需要定义cmp结构体,并重载运算符()

struct cmp{
	bool operator() (const int a ,const int b) const {
		 return a>b;           //表示小的数优先级高,即小的先出队 
	}
};
  1. set 集合 头文件: < set >
    set< int >s ; 就可以定义一个set了 set是一个已排序的无重复元素的集合
    set的常用操作:
    s.begin() 返回集合中的第一个元素的迭代器
    s.end() 返回集合中的最后一个元素的迭代器
    s.clear() 清空集合中的所有元素
    s.empty() 判断集合是否为空
    s.size() 返回集合当前元素的个数
    s.insert() 向集合中插入元素
    s.earse(it) //慎用,易出错,参数为迭代器

如何访问set呢,就要使用迭代器了。迭代器类似于指针,能够用来遍历set
下面给一个例子

for(set<string>::iterator it = s.begin();it!=end();it++){
		cout<<*it<<endl;
	} 
	

你可能感兴趣的:(算法总结)