STL算法
STL提供了大概80种算法,可以分为4类:
1.非修改性算法:这类算法不改变容器中的内容,只是从容器获取信息。
2.修改性算法: 这类算法通过插入、删除、重排等操作改变容器包含的元素,以及修改元素的值。
3.数值算法: 数值算法提供了4种数值操作,用具计算累计、临差、部分和、内积。
4.堆算法: 堆算法提供了4种操作,用于创建堆、从堆中删除元素、向堆中插入元素、排序堆。
数值算法包含在<numeric>头文件中,所有其他算法都包含在<algorithm>头文件中。
所有算法都是通过迭代器对容器进行操作。容器vector、deque支持随机访问迭代器,list、set、multiset、map、multimap支持双向迭
代器。很多算法都是对由两个迭代器限定的一个元素序列进行操作,第一个迭代器指出序列的第一个元素,第二个迭代器指出序列最
后一个元素之后的位置。
函数copy:
函数copy用于将一个容器中的元素序列复制到另一个容器。函数原型:
template<typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator beg, InputIterator end, OutputIterator targetPosition)
函数将源容器beg....end - 1间的元素复制到目标容器targetPosition起始的位置,其中beg和end是源容器中的迭代器,targetPosition
是目标容器中的迭代器,函数返回的是指向复制的最后一个元素之后的迭代器。
我们可以将元素从数组复制到容器,也可以将元素从容器复制到数组和输出流。
一个使用copy的例子:
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
using namespace std;
int main()
{
int values[] = {1, 2, 3, 4, 5, 4, 3};
vector<int> intVector(values, values + 6);
list<int> intList(values, values + 6);
copy(values, values + 4, intVector.begin());
copy(values + 3, values + 5, intList.begin());
cout<<"inVector:";
for(int i = 0; i < intVector.size(); i++)
{
cout<<intVector[i]<<" ";
}
cout<<"\nintList:";
for(list<int>::iterator p = intList.begin(); p != intList.end(); p++)
{
cout<<*p<<" ";
}
cout<<endl;
ostream_iterator<int> output(cout, "--"); //输出迭代器
cout<<"use ostream_iterator:";
//将容器中的元素复制到输出迭代器中
copy(intVector.begin(), intVector.begin() + intVector.size() - 1, output);
*output = 99;
*output;
return 0 ;
}
函数fill和fill_n
函数fill用于将指定值填入容器beg至end-1之间的元素中,语法如下:
template <typename ForwardIterator, typename T>
void fill(ForwardIterator beg, ForwardIterator end, const T & value)
函数fill_n用于将指定值填入容器beg至beg + n - 1之间的元素中,语法如下:
template <typename ForwardIterator, typename size, typename T>
void fill_n(ForwardIterator beg, size n, const T & value)
还是看例子吧:
#include <iostream>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
int main()
{
int values[] = {1, 2, 3, 4, 5, 6};
list<int> intList(values, values + 6);
ostream_iterator<int> output(cout, " ");
cout<<"intList:";
copy(intList.begin(), intList.end(), output);
fill_n(intList.begin(), 2, 66);
cout<<"\nuse fill_n():";
copy(intList.begin(), intList.end(), output);
fill(values + 3, values + 4, 88);
cout<<"\nuse fill():";
copy(values, values + 6, output);
return 0;
}
函数generate和generate_n
函数generate和generate_n用某个函数返回的值填写容器中的元素序列。语法如下:
template <typename ForwardIterator, typename function>
void generate(ForwardIterator beg, ForwardIterator end, function gen)
template <typename ForwardIterator, typename size, typename function>
void generate_n(ForwardIterator beg, size n, function gen)
例子:
#include <iostream>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
int nextnum()
{
static int n = 20;
return n++;
}
int main()
{
int values[] = {1, 2, 3, 4, 5, 6};
list<int> intList(values, values + 6);
ostream_iterator<int> output(cout, " ");
cout<<"intList:";
copy(intList.begin(), intList.end(), output);
generate_n(intList.begin(), 3, nextnum);
cout<<"\nuse generate_n():";
copy(intList.begin(), intList.end(), output);
generate(values + 1, values + 3, nextnum);
cout<<"\nuse generate():";
copy(values, values + 6, output);
return 0;
}
函数remove、remove_if、 remove_copy、remove_copy_if
函数remove删除元素序列中与给定值value匹配的元素,语法如下:
template <typename ForwardIterator, typename T>
ForwardIterator remove(ForwardIterator beg, ForwardIterator end, const T & value)
函数remove_if删除元素序列中所有使函数boolFunction(element)为真的元素,语法如下:
template <typename ForwardIterator, typename boolFunction>
ForwardIterator remove_if(ForwardIterator beg, ForwardIterator end, boolFunction f)
函数remove和remove_if都返回一个指向新元素区域尾元素之后位置的迭代器。
函数remove_copy将序列中所有元素复制到目标容器中,略过其中与给定值匹配的元素。
函数remove_copy_if将序列中所有元素复制到目标容器,略过其中一些元素,这些元素使得函数boolFunction(element)为真。
#include <iostream>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
bool greater3(int value)
{
return value > 3;
}
int main()
{
int values[] = {1, 2, 3, 4, 3, 6, 3, 2, 3};
list<int> intList(values, values + 6);
ostream_iterator<int> output(cout, " ");
cout<<"intList:";
copy(intList.begin(), intList.end(), output);
remove(values, values + 6, 3);
cout<<"\nuse remove():";
copy(values, values + 6, output);
remove_if(intList.begin(), intList.end(), greater3);
cout<<"\nuse remove)_if():";
copy(intList.begin(), intList.end(), output);
return 0;
}
函数replace、replace_if、replace_copy、replace_copy_if
函数replace将序列中所有与给定值相等的元素替换为新值,语法如下:
template<class ForwardIterator, class Type>
void replace(ForwardIterator _First, ForwardIterator _Last, const Type& _OldVal, const Type& _NewVal );
函数replace_if将序列中所有满足boolFunction(element)为真的元素替换为新值。
函数replace_copy将序列中所有与给定值相等的元素替换为新值,将结果复制到目标容器。
函数replace_copy_if将序列中所有boolFunction(element)为真的元素替换为新值,将结果复制到目标容器
函数find、find_if、find_end、find_first_of
函数find搜索一个元素,语法如下:
template<class InputIterator, class Type>
InputIterator find( InputIterator _First, InputIterator _Last, const Type& _Val );
函数find_if搜索满足boolFunction(element)为真的元素
如果搜索成功,find和find_if都返回指向第一个匹配的元素的迭代器。
函数find_end用于搜索一个子序列:
函数find_first_of搜索一个序列中某个元素在第二个序列中第一次出现的位置。
函数search和search_n
search和find_end类似,都是搜索一个子序列,find_end搜索最后匹配子序列,而search搜索第一个匹配的位置。如果搜索成功,两
个函数都返回第一个匹配子序列的位置。
search_n搜索序列中一个值连续出现的情况。
函数sort和binary_search
函数sort需要使用随机访问迭代器,它可以用来排序数组、向量或双端队列。有两个版本:
template<class RandomAccessIterator>
void sort(
RandomAccessIterator first,
RandomAccessIterator last
);
template<class RandomAccessIterator, class Predicate>
void sort(
RandomAccessIterator first,
RandomAccessIterator last,
Predicate comp
);
函数binary_search在一个有序序列中搜索一个值。也有两个版本:
template<class ForwardIterator, class Type>
bool binary_search(
ForwardIterator _First,
ForwardIterator _Last,
const Type& _Val
);
template<class ForwardIterator, class Type, class BinaryPredicate>
bool binary_search(
ForwardIterator _First,
ForwardIterator _Last,
const Type& _Val,
BinaryPredicate _Comp
);
注意要点:有些STL算法允许传递运算符函数,实际上是向STL函数传递了一个指向函数对象的指针。
函数对象有三种类型:关系、逻辑、算术。
sort和binary_search算法需要传递关系运算符。
一个例子:
#include <iostream>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
int main()
{
int values[] = {1, 2, 3, 4, 3, 6, 3, 2, 3};
list<int> intList(values, values + 9);
ostream_iterator<int> output(cout, " ");
cout<<"intList:";
copy(intList.begin(), intList.end(), output);
sort(values, values + 9); //默认是升序
cout<<"\nvalues[]:";
copy(values, values + 9, output);
cout<<(binary_search(values, values + 9, 4)? "\n 4 is in values[]\n":"\ns is no in values[]\n");
sort(values, values + 9, greater<int>()); //用降序排列
cout<<"\n use greater<int>() values[]:";
copy(values, values + 9, output);
return 0;
}
函数reverse和reverse_copy
函数reverse将序列中元素反转,函数reverse_copy将序列中元素逆序复制到另一个序列中,函数reverse_copy不会改变源序列内容
函数原型:
template<class BidirectionalIterator>
void reverse(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template<class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy(
BidirectionalIterator _First,
BidirectionalIterator _Last,
OutputIterator _Result
);
函数rotate和rotate_copy
函数rotate将一个序列中的元素旋转:语法如下:
template<class ForwardIterator>
void rotate(
ForwardIterator _First,
ForwardIterator _Middle,
ForwardIterator _Last
);
函数rotate_copy类似rotate,但不是旋转源序列,而是将结果复制到目标序列,
template<class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy(
ForwardIterator _First,
ForwardIterator _Middle,
ForwardIterator _Last,
OutputIterator _Result
);
函数adjacent_find、merge、inplace_merge
adjacent_find搜索序列中第一对相等(或满足boolFunction(element))的相邻元素。
merge将两个有序序列合并为一个新序列
inplace_merge将序列的第一部分和第二部分合并,假定两部分都已是有序的子序列。结果保存在原序列中,也称为原址合并(inplace merge)
#include <iostream>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
int main()
{
int values[] = {1, 8, 3, 2, 5, 1, 7, 6};
list<int> intList(8);
ostream_iterator<int> output(cout, " ");
cout<<"values:";
copy(values, values + 8, output);
sort(values, values + 3);
sort(values + 3, values + 8);
cout<<"\nafter sort:";
copy(values, values + 8, output);
//将两个有序序列合并为一个新序列
merge(values, values + 3, values + 3, values + 8, intList.begin());
cout<<"\nmerge,intList:";
copy(intList.begin(), intList.end(), output);
//原址合并
inplace_merge(values, values + 3, values + 8);
cout<<"\ninplace merge, values:";
copy(values, values + 8, output);
return 0;
}