template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
template< class InputIt, class OutputIt, class UnaryPredicate >
OutputIt copy_if( InputIt first, InputIt last, OutputIt d_first, UnaryPredicate pred );
将[first, last)复制到d_first指向的位置,d_first不能在[first, last)范围内。
#include
#include
#include
#include
#include
int main()
{
std::vector<int> from_vector(10);
std::iota(from_vector.begin(), from_vector.end(), 0); // std::iota 用顺序递增的值赋值指定范围内的元素。
std::vector<int> to_vector;
// std::back_inserter函数:配合copy函数,把[a, b)区间的数据插入到string对象的末尾,如果容量不够,动态扩容
std::copy(from_vector.begin(), from_vector.end(), std::back_inserter(to_vector));
// or, alternatively,
// std::vector to_vector(from_vector.size());
// std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
// either way is equivalent to
// std::vector to_vector = from_vector;
std::cout << "to_vector contains: ";
std::copy(to_vector.begin(), to_vector.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
Output:
to_vector contains: 0 1 2 3 4 5 6 7 8 9
template< class InputIt, class Size, class OutputIt >
OutputIt copy_n( InputIt first, Size count, OutputIt result );
将first开始的count个数据复制到result中。
#include
#include
#include
#include
int main()
{
std::string in = "1234567890";
std::string out;
// std::back_inserter函数:配合copy函数,把[a, b)区间的数据插入到string对象的末尾,如果容量不够,动态扩容
std::copy_n(in.begin(), 4, std::back_inserter(out));
std::cout << out << '\n';
}
Output:
1234
template< class BidirIt1, class BidirIt2 >
BidirIt2 copy_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
将[first, last)以相反的顺序复制(最后一个元素首先复制)到d_last结尾的新地址中,但保留它们的相对顺序。
#include
#include
#include
int main()
{
std::vector<int> from_vector;
for (int i = 0; i < 10; i++) {
from_vector.push_back(i);
}
std::vector<int> to_vector(15);
std::copy_backward(from_vector.begin(), from_vector.end(), to_vector.end());
std::cout << "to_vector contains: ";
for (auto i: to_vector) {
std::cout << i << " ";
}
}
Output:
to_vector contains: 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last, OutputIt d_first );
将[first, last)移动到d_first开始的新空间内。
将线程对象(它们本身不可复制)从一个容器移动到另一个容器。
#include
#include
#include
#include
#include
#include
void f(int n)
{
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "thread " << n << " ended" << '\n';
}
int main()
{
std::vector<std::thread> v;
v.emplace_back(f, 1);
v.emplace_back(f, 2);
v.emplace_back(f, 3);
std::list<std::thread> l;
// copy() would not compile, because std::thread is noncopyable
std::move(v.begin(), v.end(), std::back_inserter(l));
for (auto& t : l) t.join();
}
Output:
thread 1 ended
thread 2 ended
thread 3 ended
template< class BidirIt1, class BidirIt2 >
BidirIt2 move_backward( BidirIt1 first, BidirIt1 last, BidirIt2 d_last );
将[first, last)以相反的顺序移动(最后一个元素首先移动)到d_last结尾的新地址中,但保留它们的相对顺序。
#include
#include
#include
#include
int main()
{
std::vector<std::string> src{"foo", "bar", "baz"};
std::vector<std::string> dest(src.size());
std::cout << "src: ";
for (const auto &s : src) {
std::cout << s << ' ';
}
std::cout << "\ndest: ";
for (const auto &s : dest) {
std::cout << s << ' ';
}
std::cout << '\n';
std::move_backward(src.begin(), src.end(), dest.end());
std::cout << "src: ";
for (const auto &s : src) {
std::cout << s << ' ';
}
std::cout << "\ndest: ";
for (const auto &s : dest) {
std::cout << s << ' ';
}
std::cout << '\n';
}
Output:
src: foo bar baz
dest:
src:
dest: foo bar baz
template< class ForwardIt, class T >
void fill( ForwardIt first, ForwardIt last, const T& value );
将value复制到[first, last)的每一个元素中
#include
#include
#include
int main()
{
std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::fill(v.begin(), v.end(), -1);
for (auto elem : v) {
std::cout << elem << " ";
}
std::cout << "\n";
}
Output:
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
template< class OutputIt, class Size, class T >
OutputIt fill_n( OutputIt first, Size count, const T& value );
将value复制到first开始的count个元素中。
#include
#include
#include
#include
int main()
{
std::vector<int> v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::fill_n(v1.begin(), 5, -1);
std::copy(begin(v1), end(v1), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
Output:
-1 -1 -1 -1 -1 5 6 7 8 9
template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op );
将unary_op函数作用到[first, last)中每一个元素,并将结果保存在d_first开始的目标区域
#include
#include
#include
#include
#include
int main()
{
std::string s("hello");
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) -> unsigned char { return std::toupper(c); });
std::vector<std::size_t> ordinals;
std::transform(s.begin(), s.end(), std::back_inserter(ordinals),
[](unsigned char c) -> std::size_t { return c; });
std::cout << s << ':';
for (auto ord : ordinals) {
std::cout << ' ' << ord;
}
}
Output:
HELLO: 72 69 76 76 79
template< class ForwardIt, class Generator >
void generate( ForwardIt first, ForwardIt last, Generator g );
为[first, last)范围内的每个元素分配由给定功能对象g生成的值。
#include
#include
#include
int f()
{
static int i = 1;
return i++;
}
int main()
{
std::vector<int> v(5);
std::generate(v.begin(), v.end(), f);
std::cout << "v: ";
for (auto iv: v) {
std::cout << iv << " ";
}
std::cout << "\n";
// Initialize with default values 0,1,2,3,4 from a lambda function Equivalent to std::iota(v.begin(), v.end(), 0);
std::generate(v.begin(), v.end(), [n = 0] () mutable { return n++; });
std::cout << "v: ";
for (auto iv: v) {
std::cout << iv << " ";
}
std::cout << "\n";
}
Output:
v: 1 2 3 4 5
v: 0 1 2 3 4
template< class OutputIt, class Size, class Generator >
OutputIt generate_n( OutputIt first, Size count, Generator g );
为first开始count个元素分配由给定功能对象g生成的值。
#include
#include
#include
#include
#include
int main()
{
std::mt19937 rng; // std::mt19937是一种随机数算法,用法与rand()函数类似;默认构建,种子为固定种子
// std::ref 用于包装按引用传递的值
std::generate_n(std::ostream_iterator<std::mt19937::result_type>(std::cout, " "), 5, std::ref(rng));
std::cout << '\n';
}
Output:
3499211612 581869302 3890346734 3586334585 545404204
template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );
template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );
删除满足特定条件的元素,删除是通过移动完成的,remove调用后指向新末端,然后再调用容器的erase删除新末端到原来末端的元素。
注意:
不能在std::set、std::map中使用。
#include
#include
#include
#include
int main()
{
std::string str1 = "Text with some spaces";
str1.erase(std::remove(str1.begin(), str1.end(), ' '),
str1.end());
std::cout << str1 << '\n';
std::string str2 = "Text\n with\tsome \t whitespaces\n\n";
str2.erase(std::remove_if(str2.begin(),
str2.end(),
[](unsigned char x){return std::isspace(x);}),
str2.end());
std::cout << str2 << '\n';
}
Output:
Textwithsomespaces
Textwithsomewhitespaces
template< class InputIt, class OutputIt, class T >
OutputIt remove_copy( InputIt first, InputIt last, OutputIt d_first, const T& value );
template< class InputIt, class OutputIt, class UnaryPredicate >
OutputIt remove_copy_if( InputIt first, InputIt last, OutputIt d_first, UnaryPredicate p );
将[first, last)范围内的元素复制到d_first开始的位置,并忽略满足条件的元素
#include
#include
#include
#include
int main()
{
std::string str = "Text with some spaces";
std::cout << "before: " << str << "\n";
std::cout << "after: ";
std::remove_copy(str.begin(), str.end(),
std::ostream_iterator<char>(std::cout), ' ');
std::cout << '\n';
}
Output:
before: Text with some spaces
after: Textwithsomespaces
template< class ForwardIt, class T >
void replace( ForwardIt first, ForwardIt last, const T& old_value, const T& new_value );
template< class ForwardIt, class UnaryPredicate, class T >
void replace_if( ForwardIt first, ForwardIt last, UnaryPredicate p, const T& new_value );
将满足特定条件的所有值替换为另一个值。
#include
#include
#include
#include
int main()
{
std::array<int, 10> s{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
std::replace(s.begin(), s.end(), 8, 88);
for (int a : s) {
std::cout << a << " ";
}
std::cout << '\n';
std::replace_if(s.begin(), s.end(),
std::bind(std::less<int>(), std::placeholders::_1, 5), 55); // 将小于5的值替换成55
for (int a : s) {
std::cout << a << " ";
}
std::cout << '\n';
}
Output:
5 7 4 2 88 6 1 9 0 3
5 7 55 55 88 6 55 9 55 55
template< class InputIt, class OutputIt, class T >
OutputIt replace_copy( InputIt first, InputIt last, OutputIt d_first, const T& old_value, const T& new_value );
template< class InputIt, class OutputIt, class UnaryPredicate, class T >
OutputIt replace_copy_if( InputIt first, InputIt last, OutputIt d_first, UnaryPredicate p, const T& new_value );
将[first, last)范围内满足条件的值替换成新值new_value,并复制到d_first开始的范围内。
#include
#include
#include
#include
#include
int main()
{
std::vector<int> v{5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
std::replace_copy_if(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int n){return n > 5;}, 99);
std::cout << '\n';
}
Output:
5 99 4 2 99 99 1 99 0 3
template< class T >
void swap( T& a, T& b ) noexcept;
交换存储在两个对象中的值。
注意:从c++11开始头文件为
#include
#include
int main()
{
int a = 5, b = 3;
// before
std::cout << a << ' ' << b << '\n';
std::swap(a,b);
// after
std::cout << a << ' ' << b << '\n';
}
Output:
5 3
3 5
template< class ForwardIt1, class ForwardIt2 >
ForwardIt2 swap_ranges( ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2 );
将[first1,last1)范围内的元素和first2开始的范围内的元素做交换。
#include
#include
#include
#include
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5};
std::list<int> l = {-1, -2, -3, -4, -5};
std::swap_ranges(v.begin(), v.begin()+3, l.begin());
for(int n : v)
std::cout << n << ' ';
std::cout << '\n';
for(int n : l)
std::cout << n << ' ';
std::cout << '\n';
}
Output:
-1 -2 -3 4 5
1 2 3 -4 -5
template< class ForwardIt1, class ForwardIt2 >
void iter_swap( ForwardIt1 a, ForwardIt2 b );
交换两个迭代器指向的元素
// 选择排序
#include
#include
#include
#include
#include
template<class ForwardIt>
void selection_sort(ForwardIt begin, ForwardIt end)
{
for (ForwardIt i = begin; i != end; ++i)
std::iter_swap(i, std::min_element(i, end));
}
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(-10, 10);
std::vector<int> v;
generate_n(back_inserter(v), 20, bind(dist, gen));
std::cout << "Before sort: ";
for(auto e : v) std::cout << e << " ";
selection_sort(v.begin(), v.end());
std::cout << "\nAfter sort: ";
for(auto e : v) std::cout << e << " ";
std::cout << '\n';
}
Output:
Before sort: -7 6 2 4 -1 6 -9 -1 2 -5 10 -9 -5 -3 -5 -3 6 6 1 8
After sort: -9 -9 -7 -5 -5 -5 -3 -3 -1 -1 1 2 2 4 6 6 6 6 8 10
template< class BidirIt >
void reverse( BidirIt first, BidirIt last );
将[first, last)范围内元素的顺序反转。
#include
#include
#include
#include
int main()
{
std::vector<int> v{1,2,3};
std::reverse(std::begin(v), std::end(v));
for(auto e : v) std::cout << e;
std::cout << '\n';
int a[] = {4, 5, 6, 7};
std::reverse(std::begin(a), std::end(a));
for(auto e : a) std::cout << e;
}
Output:
321
7654
template< class BidirIt, class OutputIt >
OutputIt reverse_copy( BidirIt first, BidirIt last, OutputIt d_first );
将[first, last)范围内元素的顺序反转,并复制到d_first开始的范围内。
#include
#include
#include
int main()
{
std::vector<int> v({1,2,3});
for (const auto& value : v) {
std::cout << value << " ";
}
std::cout << '\n';
std::vector<int> destination(3);
std::reverse_copy(std::begin(v), std::end(v), std::begin(destination));
for (const auto& value : destination) {
std::cout << value << " ";
}
std::cout << '\n';
}
Output:
1 2 3
3 2 1
template< class ForwardIt >
ForwardIt rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );
循环移动,将[first, n_first)+[n_first, last),变成[n_first, last)+[first, n_first);
#include
#include
#include
int main()
{
std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1};
std::cout << "before sort: ";
for (int n: v)
std::cout << n << ' ';
std::cout << '\n';
// 插入排序
for (auto i = v.begin(); i != v.end(); ++i) {
std::rotate(std::upper_bound(v.begin(), i, *i), i, i+1);
}
std::cout << "after sort: ";
for (int n: v)
std::cout << n << ' ';
std::cout << '\n';
// simple rotation to the left
std::rotate(v.begin(), v.begin() + 1, v.end());
std::cout << "simple rotate left : ";
for (int n: v)
std::cout << n << ' ';
std::cout << '\n';
// simple rotation to the right
std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
std::cout << "simple rotate right : ";
for (int n: v)
std::cout << n << ' ';
std::cout << '\n';
}
Output:
before sort: 2 4 2 0 5 10 7 3 7 1
after sort: 0 1 2 2 3 4 5 7 7 10
simple rotate left : 1 2 2 3 4 5 7 7 10 0
simple rotate right: 0 1 2 2 3 4 5 7 7 10
template< class ForwardIt, class OutputIt >
OutputIt rotate_copy( ForwardIt first, ForwardIt n_first, ForwardIt last, OutputIt d_first );
循环移动后复制到d_first开始的范围内,将[first, n_first)+[n_first, last),变成[n_first, last)+[first, n_first);
#include
#include
#include
int main()
{
std::vector<int> src = {1, 2, 3, 4, 5};
auto pivot = std::find(src.begin(), src.end(), 3);
std::vector<int> dest(src.size());
std::rotate_copy(src.begin(), pivot, src.end(), dest.begin());
for (const auto &i : dest) {
std::cout << i << ' ';
}
std::cout << '\n';
}
Output:
3 4 5 1 2
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g );
对[first,last)范围内的元素随机排序
#include
#include
#include
#include
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
}
Possible output:
8 6 10 4 2 3 7 1 9 5
template< class ForwardIt >
ForwardIt unique( ForwardIt first, ForwardIt last );
template< class ForwardIt, class BinaryPredicate >
ForwardIt unique( ForwardIt first, ForwardIt last, BinaryPredicate p );
删除指定范围内连续重复的元素。使用时,先排序,再删除重复元素(这里的删除只是将新序列移动到前面),最后使用erase做真正删除动作。
#include
#include
#include
#include
#include
int main()
{
// 删除重复的元素
std::vector<int> v{1,2,3,1,2,3,3,4,5,4,5,6,7};
std::sort(v.begin(), v.end()); // 1 1 2 2 3 3 3 4 4 5 5 6 7
auto last = std::unique(v.begin(), v.end());
// v now holds {1 2 3 4 5 6 7 x x x x x x}, where 'x' is indeterminate
v.erase(last, v.end());
for (int i : v)
std::cout << i << " ";
std::cout << "\n";
}
Output:
1 2 3 4 5 6 7
template< class InputIt, class OutputIt >
OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first );
template< class InputIt, class OutputIt, class BinaryPredicate >
OutputIt unique_copy( InputIt first, InputIt last, OutputIt d_first, BinaryPredicate p );
将[first,last)范围内,剔除重复项后复制到d_first开始的范围内。
#include
#include
#include
#include
int main()
{
std::string s1 = "The string with many spaces!";
std::cout << "before: " << s1 << '\n';
std::string s2;
std::unique_copy(s1.begin(), s1.end(), std::back_inserter(s2),
[](char c1, char c2){ return c1 == ' ' && c2 == ' '; });
std::cout << "after: " << s2 << '\n';
}
Output:
before: The string with many spaces!
after: The string with many spaces!
这两个算法是C++20以后才有的新算法,暂时不学
这个算法是C++17以后才有的新算法,暂时不学