STL之算法(二)
变动型算法介绍
copy
- 拷贝一段区间到指定的内存位置
- 如果是非内置类型, 则需要该类型具有
operator=和拷贝构造函数. - copy的目标必须有
对象的存在, 因为它最终是要调用对象的operator=. - 可以
跨容器拷贝 - 不改变原容器内容
copy_n
- 拷贝从给定的开始范围, 指定个数的拷贝到给定的内存位置
- 不改变原容器内容
copy_if
- 有选择性的拷贝
- 拷贝区间范围内所有满足 if 条件的项到指定的位置
- 不改变原容器内容
copy_backward
- 倒序从给定的 end 位置往前拷贝
- 不改变原容器内容
#include <iostream> // std::cout
#include <algorithm> // std::copy_backward
#include <vector> // std::vector
int main () {
std::vector<int> myvector;
// set some values:
for (int i=1; i<=5; i++)
myvector.push_back(i*10); // myvector: 10 20 30 40 50
myvector.resize(myvector.size()+3); // allocate space for 3 more elements
std::copy_backward ( myvector.begin(), myvector.begin()+5, myvector.end() );
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}swap
- 交换函数
- 可以交换值, 数组(C11)
- 会改变原容器内容
swap_ranges
- 区间交换
- 将区间1的数据和区间2的数据进行交换
- 必须保证区间2的长度 大于 区间1的长度.
- 会改变原容器内容
iter_swap
- 迭代器交换
- 会改变原容器内容
transform
- 将某操作应用于指定范围的每个元素
- 会改变指定的第二个result容器的内容, 不改变第一个容器的内容
#include <iostream> // std::cout
#include <algorithm> // std::transform
#include <vector> // std::vector
#include <functional> // std::plus
int op_increase (int i) { return ++i; }
int main () {
std::vector<int> foo;
std::vector<int> bar;
// set some values:
for (int i=1; i<6; i++)
foo.push_back (i*10); // foo: 10 20 30 40 50
bar.resize(foo.size()); // allocate space
std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
// bar: 11 21 31 41 51
// std::plus adds together its two arguments:
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
// foo: 21 41 61 81 101
std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}replace
- 在指定的区间内进行新值和老值的替换
- 会修改原容器的内容
replace_if
- 在指定的区间内对指定符合条件的值进行替换成新值
- 会修改原容器的内容
replace_copy
- 对指定区间内进行拷贝到新的内存空间, 在拷贝的同时进行老值使用新值的替换
- 不修改本身的容器
replace_copy_if
- 对指定区间内进行拷贝到新的内存空间, 在拷贝的同时进行指定条件的判断, 以替换成新值
- 不修改本身的容器
fill
- 将指定的范围填充成给定的值
- 会改变原容器的内容
fill_n
- 从指定的位置开始填充给定的位数为给定的值
- 会返回一个迭代器
- 会改变原容器的内容
generate
- 将一个生成函数的返回值填充到指定的范围
- 会改变原容器的内容
generate_n
- 将一个生成函数的返回值填充到指定的位置, 填充指定位数个.
- 会改变原容器的内容
remove
- 删除指定范围内的指定值
- 会存在垃圾数据
- 会返回处理后的容器的有效值的end()
- 可以配合resize()进行删除
- 会改变原容器的内容
remove_if
- 删除指定范围内的符合 if 条件的值
- 会存在垃圾数据
- 会返回处理后的容器的有效值的end()
- 可以配合resize()进行删除
- 会改变原容器的内容
remove_copy
- 拷贝到新的容器中, 同时删除指定范围内的指定值
- 新容器中不会存在垃圾数据
- 不会改变原容器的内容
remove_copy_if
- 拷贝到新的容器中, 同时删除指定范围内的符合 if 条件的值
- 新容器中不会存在垃圾数据
- 不会改变原容器的内容
unique
- 对指定范围的连续相同的元素内容去重
- 会存在垃圾数据
- 返回的是原容器有效数据的end()
- 会改变原容器的内容
#include <iostream> // std::cout
#include <algorithm> // std::unique, std::distance
#include <vector> // std::vector
bool myfunction (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {10,20,20,20,30,30,20,20,10}; // 10 20 20 20 30 30 20 20 10
std::vector<int> myvector (myints,myints+9);
// using default comparison:
std::vector<int>::iterator it;
it = std::unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ? ? ? ?
// ^
myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10
// using predicate comparison:
std::unique (myvector.begin(), myvector.end(), myfunction); // (no changes)
// print out content:
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}unique_copy
- 对指定范围的内容进行拷贝, 同时对连续相同元素的内容去重
- 新容器不会存在垃圾数据
- 不会改变原容器的内容
#include <iostream> // std::cout
#include <algorithm> // std::unique_copy, std::sort, std::distance
#include <vector> // std::vector
bool myfunction (int i, int j) {
return (i==j);
}
int main () {
int myints[] = {10,20,20,20,30,30,20,20,10};
std::vector<int> myvector (9); // 0 0 0 0 0 0 0 0 0
// using default comparison:
std::vector<int>::iterator it;
it=std::unique_copy (myints,myints+9,myvector.begin()); // 10 20 30 20 10 0 0 0 0
// ^
std::sort (myvector.begin(),it); // 10 10 20 20 30 0 0 0 0
// ^
// using predicate comparison:
it=std::unique_copy (myvector.begin(), it, myvector.begin(), myfunction);
// 10 20 30 20 30 0 0 0 0
// ^
myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30
// print out content:
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}reverse
- 对指定范围进行反序
- 迭代器必须支持
--操作(双向迭代器) - 会改变原容器的内容
reverse_copy
- 对指定范围进行拷贝到新容器, 并且同时反序
- 迭代器必须支持
--操作. - 不会改变原容器的内容
rotate
对给定的范围, 按照设定的中间位置进行反转
- 比如, {1, 2, 3, 4, 5, 6, 7, 8 }
- 执行 rotate(begin(), begin() + 3, end());
- 结果为 {4, 5, 6, 7, 8, 1, 2, 3}
- 会改变原容器内容
rotate_copy
对给定的范围复制到新的容器中, 并按照设定的中间位置进行反转
- 效果见rotate
- 不会改变原容器内容
random_shuffle
- 对给定的范围进行随机乱序处理
- 需要
随机访问迭代器的支持 - 会改变原容器的内容
- 值是原容器中的, 顺序会改变但是值不会改变.
shuffle
- 对给定的范围进行随机乱序处理
- 需要
前向迭代器的支持 - 会改变原容器的内容
- 值是原容器中的, 顺序会改变但是值不会改变.
未完待续...
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-04-14 at 04:12 pm