C++ STL算法
Reference:
- 明日科技 《零基础学 C++》
算法是 STL 的中枢,STL 提供了算法库,算法库中都是模板函数。迭代器主要负责从容器中获取一个对象,算法与具体对象在容器中的什么位置等细节不用考虑。每个算法都是参数化一个或多个迭代器类型的函数模板。
标准算法分 4 个类别:非修正序列算法、修正序列算法、排序算法和数值算法。
1. 非修正序列算法
非修正序列算法
不修改它们所作用的容器,例如计算元素个数或查找元素的函数。STL 中提供的非修正序列算法如下所示:
函数 | 说明 |
---|---|
adjacent_find(first,last) | 搜索相邻的重复元素 |
count(first,last,val) | 计数 |
equal(first,last,first2) | 判断是否相等 |
find(first,last,val) | 搜索 |
find_end(first,last,first2,last2) | 搜索某个子序列的最后一次出现地点 |
find_first(first,last,first2,last2) | 搜索某些元素的首次出现地点 |
for_each(first,last,func) | 对 first 到 last 范围内的各个元素执行函数 func 定义的操作 |
mismatch(first,last,first2) | 找出不吻合点 |
search(first,last,first2,last2) | 搜索某个子序列 |
1.1 adjacent_find(first,last)
返回一个迭代器,指向第一对同值元素对的第一个元素。函数在迭代器 first 和 last 指明的范围内查找。
multiset<int, less<int> > intSet;
intSet.insert(7);
intSet.insert(5);
intSet.insert(1);
intSet.insert(5);
intSet.insert(7); // 1 5 5 7 7
multiset<int, less<int> >::iterator it;
it = adjacent_find(intSet.begin(), intSet.end());
cout << "第一次匹配:" << *it++ << ' ' << *it; //第一次匹配:5 5
it = adjacent_find(it,intSet.end());
cout << "第二次匹配:" << *it++ << ' ' << *it; //第二次匹配:7 7
程序中定义了整型的 multiset 容器,以及该容器的迭代器 it,在 multiset 容器中有两个重复的值,使用 adjacent_find 算法将这两个元素输出。
1.2 count(first,last,val)
返回容器中值为 val 的元素个数。函数在迭代器 first 和 last 指明的范围内查找。
multiset<int, less<int> > intSet;
intSet.insert(7);
intSet.insert(5);
intSet.insert(1);
intSet.insert(5);
intSet.insert(7); // 1 5 5 7 7
int cnt = count(intSet.begin(), intSet.end(), 5); // 计算容器中相同元素的数量
cout << "相同元素数量: " << cnt << endl; // 相同元素数量: 2
2. 修正序列算法
修正序列算法
的有些操作会改变容器的内容。例如,把一个容器的部分内容复制到同一个容器的另一部分,或者用指定值填充容器。STL 的修正序列算法能够提供这类操作。
函数 | 说明 |
---|---|
copy(first,last,first2) | 复制 |
copy_backward(first,last,first2) | 逆向复制 |
fill(first,last,val) | 改填元素值 |
generate(first,last,func) | 以指定动作的运算结果填充特定范围内的元素 |
partition(first,last,pred) | 切割 |
random_shuffle(first,last) | 随机重排 |
remove(first,last,val) | 移除某种元素,但不删除 |
replace(first,last,val1,val2) | 取代某种元素 |
rotate(first,middle,last) | 旋转 |
reverse(first,last) | 颠倒元素次序 |
swap(it1,it2) | 置换 |
swap_ranges(first,last,first2) | 置换指定范围 |
transform(first,last,first2,func) | 以两个序列为基础,交互作用产生第三序列 |
unique(first,last) | 将重复的元素折叠缩编,变成唯一的 |
2.1 random_shuffle(first,last)
把迭代器 first 和 last 指明范围内的元素顺序随机打乱。
void Output(int val){
cout << val << ' ';
}
vector<int> intVect;
for(int i=0; i<10; ++i) // for循环中写i++或者是++i是不影响输出结果的
intVect.push_back(i);
for_each(intVect.begin(),intVect.end(),Output); // 0 1 2 3 4 5 6 7 8 9
random_shuffle(intVect.begin(),intVect.end());
for_each(intVect.begin(),intVect.end(),Output); // 4 3 0 2 6 7 8 9 5 1
可以看到打乱后的元素顺序没有任何规律。
2.2 partition(first,last,pred)
把一个容器划分成两部分,第 1 部分包含令谓词 pred 返回 true 值的元素,第 2 部分包含令谓词 pred 返回 false 值的元素。函数返回的迭代器指向两部分的分界点元素。
void Output(int val){
cout << val << ' ';
}
bool equals5(int val){
return val==5;
}
vector<int> intVect;
intVect.push_back(7);
intVect.push_back(3);
intVect.push_back(5);
for_each(intVect.begin(),intVect.end(),Output); // 7 3 5
partition(intVect.begin(),intVect.end(),equals5);
for_each(intVect.begin(),intVect.end(),Output); // 5 3 7
3. 排序算法
排序算法
的特点是对容器的内容进行不同方式的排序。
函数 | 说明 |
---|---|
binary_search(first,last,val) | 二元搜索 |
equal_range(first,last,val) | 判断是否相等,并返回一个区间 |
includes(first,last,first2,last2) | 包含于 |
lexicographical_compare(first,last,first2,last2) | 以字典排列方式作比较 |
lower_bound(first,last,val) | 下限 |
make_heap(first,last) | 制造一个 heap |
max(val,val2) | 最大值 |
max_element(first,last) | 最大值所在位置 |
merge(first,last,first2,last2,result) | 合并两个序列 |
min(val,val2) | 最小值 |
min_element(first,last) | 最小值所在的位置 |
next_permutation(first,last) | 获得下一个排列组合 |
nth_permutation(first,last) | 重新排序列中第n个元素的左右两端 |
partial_sort_copy(first,last,first2,last2) | 局部排序并复制到其他位置 |
partial_sort(first,middle,last) | 局部排序 |
pop_heap(first,last) | 从 heap 内取出一个元素 |
push_heap(first,last) | 将一个元素压入 heap |
set_differrence(first,last,first2,last2,result) | 获得前一个排列组合 |
set_intersection(first,last,first2,last2,result) | 交集 |
set_union(first,last,first2,last2,result) | 差集 |
sort(first,last) | 排序 |
sort_heap(first,last) | 对 heap 排序 |
stable_sort(first,last) | 排序并保持等值元素的相对次序 |
upper_bound(first,last,val) | 上限 |
3.1 sort(first,last)
void Output(int val){
cout << val << ' ';
}
vector<char> charVect; //创建容器
charVect.push_back('M');
charVect.push_back('R');
charVect.push_back('K');
charVect.push_back('J');
charVect.push_back('H');
charVect.push_back('I');
for_each(charVect.begin(),charVect.end(),Output); // 77 82 75 74 72 73
sort(charVect.begin(),charVect.end());
for_each(charVect.begin(),charVect.end(),Output); // 72 73 74 75 77 82
4. 数值算法
数值算法是对容器中的内容进行数值计算。STL 的数值算法实现了 4 种类型的计算,可以在一个值序列上进行这些计算。
函数 | 说明 |
---|---|
accumulate(first,last,init) | 元素累加 |
inner_product(first,last,first2,init) | 内积 |
partial_sum(first,last,result) | 局部总和 |
adjacent_difference(first,last,result) | 相邻元素的差额 |
4.1 accumulate(first,last,init)
accumulate(first,last,init) 计算 init 与迭代器 first 和last 指明范围内各元素值的总和,并返回结果。
void Output(int val){
cout << val << ' ';
}
vector<int> intVect;
for(int i=0; i<5; i++)
intVect.push_back(i);
for_each(intVect.begin(),intVect.end(),Output); // 0 1 2 3 4
int result = accumulate(intVect.begin(),intVect.end(),5); // 计算容器指定范围内元素的和
cout << result << endl; // 15
程序对容器内的元素值进行累加,结果是 (1+2)+(2+3)+(3+4)
相关 STL 文章:
C++ STL序列容器
C++ STL关联式容器