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;
}