C++STL标准模版库、algorithm

一、概述

STL的一个重要特点就是数据结构和算法的分离

STL中包含的是堆栈、队列和其他许多标准数据结构的实现和许多重要泛化算法的实现。

STL提供大量的模版类和函数,其中最常用的是迭代器、容器、算法

为避免和其他头文件冲突以及确保移植性,在头文件书写时缺省.h后缀

二、容器

容器类库中有7种类型:

  • 向量
  • 列表
  • 双端列表
  • 集合
  • 映射
  • 队列

其中,前三个是顺序容器,中间两个是关系式容器,后两个是容器适配。

数据结构描述头文件
向量<vector>连续存储元素,就像数组,自带实用性函数方法<vector>
列表<list>由节点组成的双向链表,每个节点包含一个元素<list>
双端列表<deque>连续存储的指向不同元素的指针所组成的数组<deque>
集合<set>由结点组成的红黑树,每个结点都包含着一个元素,结点之间以某种作用于元素对的谓词排序,没有两个不同的元素能够拥有相同的次序<set>
映射<map>由{key,value}组成的集合,以某种作用于键对上的谓词排序<map>
栈<stack>后进先出顺序<stack>
队列<queue>先进先出顺序<queue>

以下使用了using namespace std;,如果没有使用需要添加std::,如std::vector<int> v;。为了编写方便,我以下都省略此操作。

1、vector

    vector<int> v;			//int型数组,是空的
    vector<int> v(10);		//int类型,定义大小为10
    vector<int> v(10,'a');	//直接初始化10个a字符
    vector<int> v(b);		//将b赋给v,b也是vector
    vector<int> v(b.begin(),b.begin()+4);	//将向量b的前五个数赋给v
    vector<int> v(a,a+4);	//a是个容量大于等于5的数组
	v.size();		//容器尺寸大小
	v.empty();		//判断v是否为空,空反1,实反0
	char *b = v.data();	//将v转变为char数组,适用于转换为字符数组
	for(vector<char>::iterator it=v.begin();it<v.end();it++)
        temp.push_back(*it);
    cout << v[3] << endl;	//直接通过中括号索引
    v[3] = 'b';				//也可以用来赋值
    cout << v.at(3) << endl;	//这也一样可以用于读取,但是不能赋值
	v.clear();			//清空v内数据,不会更改v的地址,也不会更改v的最大容量
	v.assign(10, 'a');		//从第一个开始替换为10个a,其他位置不变;如果位数不够,添加位数
	v.front();				//第一个字符
	v.front() = 'a';		//也可用于赋值
	v.back();				//一样
	v.back() = 'a';
	v.push_back('a');		//从最后面插入数
	v.pop_back();			//删除最后一个数
    v.capacity();			//获取v的最大容量(系统为它分配的大小)
//注意下面的位置不是输入的数字索引,而是position,如v.begin()、6v.end()、v.begin()+5
	v.erase(pos);		//删除pos位置的数据,传回下一个数据的位置。
	v.erase(beg,end);	//删除[beg,end)区间的数据,传回下一个数据的位置。

2、list

list是双向链表,在操作中没有[]或者at()函数可以观察,只能通过迭代器实现数据的遍历

	list<int>::iterator opt;
    for(opt = l.begin();opt != l.end(); opt++)
        cout << *opt;
	l.insert(l.begin(),9);			//开头处插入一个9
	l.insert(l.begin(),2 ,9);		//开头处插入2个9
	l.insert(l.begin(),list.begin(),list.begin()+5);	//把list表中前6个数据插入到l的开头
	l.erase(l.begin());		//删除开头1个数据
	l.sort();			//内部排序
	swap(l1,l2);		//两个表互换
	l1.swap(l2);		//等价
	l.merge(l1);		//l1合并到l中,l1在l后,并且清空l1
	l.merge(l1,greater<int>());	//l1合并到l中,l1在l前,并且清空l1

push_back() 和front()和back()等函数和vector里都一样,只是list里多了个push_front()

3、deque

构造函数和前面的统一

可从头尾双方面存取数据

成员函数略

4、set

	insert();				//插入数据
	begin();				//返回set容器的第一个元素
	end();					//返回set容器的最后一个元素
	clear();				//删除set容器中的所有的元素
	empty();				//判断set容器是否为空
	max_size();				//返回set容器可能包含的元素最大个数
	size();					//返回当前set容器中的元素个数
	rbegin();				//返回的值和end()相同
	rend();					//返回的值和rbegin()相同
	count()//用来查找set中某个某个键值出现的次数
	erase(iterator);		//删除定位器iterator指向的值
	erase(first,second);	//删除定位器first和second之间的值
	erase(key_value);		//删除键值key_value的值
	find();					//寻找值
	lower_bound(key_value);	//返回第一个大于等于key_value的定位器
	upper_bound(key_value);	//返回最后一个大于等于key_value的定位器

5、map

map与前面的不一样,它是一个一对一的容器,即key——value,根据key值,可快速访问value。

由于格式不同,所以一些操作方法也不同。

// 第一种 用insert函數插入pair
m.insert(pair<int, string>(1, "a"));
 
// 第二种将同种map类型数据插入
m.insert(map<int, string>::value_type(2, "b"));
 
// 第三种 用数组方式插入
m[3] = "c";

//输出直接套用数组模版
cout << m[2] << endl;

6、stack

栈的功能不解释,它主要是三个函数构成功能

	stack<char> s;				//定义一个char类型栈
    s.push('h');				//进栈一个元素
    cout << s.top() << endl;	//输出栈顶元素
    s.pop();					//删除栈顶元素

    s.empty();					//是否为空
    s.size();					//栈内元素个数

7、queue

队列和栈的用法大致相当

	q.push('c');				//进队
    cout << q.front() << endl;	//输出队前元素
    q.pop();					//删除队前元素
    q.empty();					//是否为空
    q.size();					//队列元素个数

三、迭代器(*/iterator)

STL有5种迭代器:

  1. 正向迭代器(forward iterator)
  2. 双向迭代器(bidirectional iterator)
  3. 随机访问迭代器(random access iterator)
  4. 输入迭代器(input iterator)
  5. 输出迭代器(output iterator)

使用方法:

1、*——指针类型

如代码:

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

int a[10];

int main(int argc, const char * argv[]) {
    
    a[6]=500;
    
    int *ite = find(a, a+sizeof(a)/sizeof(int), 500);
    if(ite == a+sizeof(a)/sizeof(int))				//ite到尾端
        cout << "not found";
    else
        cout << *ite << " was found";
    
    cout << endl;
    return 0;
}

使用的常用的指针类型,定义一个int类型指针,使用find函数,将数组中找到的地址赋给指针,所以直接拜访指针即可.

并且迭代器指针是可以直接修改数组内部值的!

2、容器中的迭代器(iterator)

如代码:

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

int main(int argc, const char * argv[]) {
    
    vector<int> v(10,5);
    v[5] = 50;
    vector<int>::iterator ite;
    
    ite = find(v.begin(), v.end(), 50);
    
    if(ite == v.end())
        cout << "not found";
    else
        cout << "found";
    
    cout << endl;
    return 0;
}

注意,end成员函数返回的是v的最后一个元素后一个位置,也就是说直接访问end是一个位置数字,但是访问end-1即是v中最后一元素。

3、常量迭代器

在前文介绍的迭代器iterator是可进行直接赋值的,那么对v或数组来说就不安全。所以引入了常量迭代器const_iterator。它的用法和iterator一样,只是,它是只读迭代器

	vector<int>::const_iterator con_ite;

四、string类型

string是最主要也是最重要的一种容器,单独列开单独讨论!

同样的,using namespace std;


赋值

	string s;
	string s("hello");
	cin >> s;

大小

	s.size();
	s.length();		//都是计算大小
	s.empty();		//查看是否为空
	s.capacity();		//重新分配内存前的最大存储个数

检索

	s[3] = 's';
	s.at(3) = 's';		//等价

比较 =0时相等,>0时表示大于,<0时表示小于

	string s("abcd");
	s.compare("abcd");		//0
	s.compare("dcba");		//<0
	s.compare("ab");		//>0
	s.compare(s);			//=0
	s.compare(0,2,s,2,2);	//<0 ab?cd
	s.compare(1,2,"bcx",2);	//<0 bc?bc

修改内容

	s.assign(str);					//str赋给s
	s.assign(str,1,3);				//把str的1索引位置后的3个字符赋给s
	s.assign(str,2,string::nopos);	//把str的2-end赋给s
	s.assign("IBM");				//字符串赋给s
	s.assign("sony",5);				//把sony以及\0赋给s
	s.assign(5,'x');				//5个x赋给s

删除

	s="";
	s.clear();
	s.erase();			//全删
	s.erase(1,2);		//删除1索引后的两个字符
	s.erase(1);			//删除1索引后的所有字符

尾端添加

	s+=str;							//把str加到s后
	s+="hello";						//把“hello”加到s后
	s+='a';							//把‘a’加到s后
	s.append(str);					//同s+=str
	s.append(str,1,3);				//将str的1-3索引字符加到s中
	s.append(str,2,string::npos);	//将str的2-end索引字符加到s中
	s.append("hello");				//同s+="hello";
	s.append("hello",3);			//把“hello”的前三个字符加到s后
	s.append(5,'x');				//把5个‘x’加到s后
	s.push_back('a');				//s后加入一个字符‘a’

插入

	s.insert(1,"hello");		//在1位置插入“hello”
	s.insert(2,str);			//在2位置插入str

替换

	s.replace(3,2,"hello");		//替换3索引后的2个字符为“hello”

提取子串

	s.substr();				//提取s的全部内容
	s.substr(11);			//提取索引11往后的字符子串
	s.substr(5,6);			//提取5索引后的6个字符子串

查找

	string s("hello world!\nGood Morning!");
	s.find("world");				//返回s中str的索引,如果不存在,返回一个超大值;返回6
	s.find_first_of("world!")		//返回“world!”中任意字符出现的最早位置;返回2
	s.find_last_of("world");		//与上一条相反;返回25
	s.find_first_not_of("help!")	//返回“help!”中没有出现的第一个字符位置;返回4
	s.find_last_not_of("help!")		//与上一条相反;返回24


记住这些关键字:find、substr、append、push_back、assign、compare

五、算法

C++ 库函数大全

在使用算法时,头文件为#include <algorithm>

提供给我们的函数接口太多了,仅写一些常用的。

成员函数:

1. find()

模版:template <class _InputIterator, class _Tp>

_InputIterator
find(_InputIterator __first, _InputIterator __last, const _Tp& __value_);

2. min()、max()

模版:template <class _Tp>

const _Tp&
min(const _Tp& __a, const _Tp& __b)

const _Tp&
max(const _Tp& __a, const _Tp& __b)

3.sort()

模版:template <class _Tp>

void
sort(_Tp** __first, _Tp** __last)

4.merge()

模版:template <class _InputIterator1, class _InputIterator2, class _OutputIterator>

_OutputIterator
merge(_InputIterator1 __first1, _InputIterator1 __last1,
      _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result)

5.binary_search()

模版:template <class _ForwardIterator, class _Tp, class _Compare>

bool
binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp)

。。。。。。

4个排序算法:sort(),partial_sort(),partial_sort_copy(),stable_sort()
4个二分查找算法:binary_search(),lower_bound(),uper_bound(),equal_range()
2个用于合并有序区间的通用算法:
merge(),inplace_merge()
4个最值算法:
min(),max(),min_element(),max_element()
3个与排列方式有关的算法:lexicographical_compare(),next_permutation(),prev_permutation()
5个用于有序序列上的集合操作算法:includes(),set_union(),set_intersection(),set_difference(),set_symmetric_difference()
4个为堆创建和操作的算法:make_heap(),pop_heap(),push_heap(),sort_heap()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值