C++ algorithm基操

序列修改

transform

功能:大小写转换

template< class InputIt, class OutputIt, class UnaryOperation >
OutputIt transform( InputIt first1, InputIt last1, OutputIt d_first,UnaryOperation unary_op );

参数:

  • first1, last1 - 要变换的第一元素范围
  • d_first - 目标范围的起始,可以等于 first1first2
  • unary_op - 将要应用的一元算符函数。

PS:记得::tolower前面有::, 而且是::tolower,不是::tolower()

#include <iostream>
#include <algorithm>
 
using namespace std;
string s;
int main() {
    cout<<"请输入一个含大写的字符串:";
    string str;
    cin>>str;
    ///转小写
    transform(str.begin(),str.end(),str.begin(),::tolower);
    cout<<"转化为小写后为:"<<str<<endl;
    transform(str.begin(),str.end(),str.begin(),::toupper);
    cout<<"转化为大写后为:"<<str<<endl;
    return 0;
}

swap

功能:交换值

void swap( T& a, T& b );

参数:

  • a, b - 要交换的值
#include <algorithm>
#include <iostream>
 
int main()
{
   int a = 5, b = 3;
 
   // 前
   std::cout << a << ' ' << b << '\n';
 
   std::swap(a,b);
 
   // 后
   std::cout << a << ' ' << b << '\n';
}

swap_ranges

功能:在范围 [first1, last1) 和始于 first2 的另一范围间交换元素。

参数

  • first1, last1 - 要交换的第一个元素范围
  • first2 - 要交换的第二个元素范围的起始

返回值
  指向始于 first2 的范围中被交换的最末元素后一元素的迭代器。

示例
  演示来自不同容器的子范围交换

#include <algorithm>
#include <list>
#include <vector>
#include <iostream>
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';
}

iter_swap

定义

template< class ForwardIt1, class ForwardIt2 >
void iter_swap( ForwardIt1 a, ForwardIt2 b );

参数

  • a, b - 指向要交换的元素的迭代器

示例
  下面是选择排序在 C++ 中的实现

#include <random>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
 
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;
    std::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';
}

reverse

定义

template< class BidirIt >
void reverse( BidirIt first, BidirIt last );

功能
  反转 [first, last) 范围中的元素顺序

参数

  • first, last - 要反转的元素的范围
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
 
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;
}

reverse_copy

定义

template< class BidirIt, class OutputIt >
OutputIt reverse_copy( BidirIt first, BidirIt last, OutputIt d_first );

功能
  复制来自范围 [first, last) 的元素到始于 d_first 的新范围,使得新范围中元素以逆序排列。

参数

  • first, last - 要复制的元素范围
  • d_first - 新范围的起始

返回值
  指向最后被复制元素后一元素的迭代器。

示例

#include <vector>
#include <iostream>
#include <algorithm>
 
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';
}

排序操作

定义于头文件 <algorithm>

sort

定义

template< class RandomIt >
void sort( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

功能
  以升序排序范围 [first, last) 中的元素。不保证维持相等元素的顺序。

    1. 用 operator< 比较元素。
    1. 用给定的二元比较函数 comp 比较元素。

参数

  • first, last - 要排序的元素范围
  • policy - 所用的执行策略。细节见执行策略。
  • comp - 比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即先序于)第二参数则返回 true

比较函数的签名应等价于如下:

bool cmp(const Type1 &a, const Type2 &b);

示例

#include <algorithm>
#include <functional>
#include <array>
#include <iostream>
 
int main()
{
    std::array<int, 10> s = {5, 7, 4, 2, 8, 6, 1, 9, 0, 3}; 
 
    // 用默认的 operator< 排序
    std::sort(s.begin(), s.end());
    for (auto a : s) {
        std::cout << a << " ";
    }   
    std::cout << '\n';
 
    // 用标准库比较函数对象排序
    std::sort(s.begin(), s.end(), std::greater<int>());
    for (auto a : s) {
        std::cout << a << " ";
    }   
    std::cout << '\n';
 
    // 用自定义函数对象排序
    struct {
        bool operator()(int a, int b) const
        {   
            return a < b;
        }   
    } customLess;
    std::sort(s.begin(), s.end(), customLess);
    for (auto a : s) {
        std::cout << a << " ";
    }   
    std::cout << '\n';
 
    // 用 lambda 表达式排序
    std::sort(s.begin(), s.end(), [](int a, int b) {
        return b < a;   
    });
    for (auto a : s) {
        std::cout << a << " ";
    } 
    std::cout << '\n';
}

最小/最大操作

max

定义

template< class T > 
const T& max( const T& a, const T& b );

template< class T, class Compare >
const T& max( const T& a, const T& b, Compare comp );

template< class T >
T max( std::initializer_list<T> ilist );

template< class T, class Compare >
T max( std::initializer_list<T> ilist, Compare comp );

功能
  返回给定值中的较大者。

  • 1-2) 返回 ab 的较大者。
  • 3-4) 返回 initializer_list ilist 中值的最大者。
  • (1,3) 版本用 operator< 比较元素, (2,4) 版本用给定的比较函数 comp

参数

  • a, b - 要比较的值
  • ilist - 拥有要比较的值的 initializer_list
  • cmp - 比较函数对象(即满足比较 (Compare) 要求的对象),若若 a 小于 b ,则返回 true

比较函数的签名应等价于如下:

bool cmp(const Type1 &a, const Type2 &b);

返回值

  • 1-2) ab 的较大者。若它们等价,则返回 a
  • 3-4) ilist 中的最大值。若有数个等价于最大者的值,则返回最左侧的这种值。

示例

#include <algorithm>
#include <iostream>
#include <string>
 
int main()
{
    std::cout << "larger of 1 and 9999: " << std::max(1, 9999) << '\n'
              << "larger of 'a', and 'b': " << std::max('a', 'b') << '\n'
              << "longest of \"foo\", \"bar\", and \"hello\": " <<
                  std::max( { "foo", "bar", "hello" },
                            [](const std::string& s1, const std::string& s2) {
                                 return s1.size() < s2.size();
                             }) << '\n';
}

max_element

定义

template< class ForwardIt > 
ForwardIt max_element(ForwardIt first, ForwardIt last );

template< class ForwardIt, class Compare >
ForwardIt max_element(ForwardIt first, ForwardIt last, Compare comp );

功能
  寻找范围 [first, last) 中的最大元素。

1) 用 operator< 比较元素。
  2) 用给定的二元比较函数 comp 比较元素。

参数

  • first, last - 定义要检验范围的向前迭代器
  • comp - 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回 true

比较函数的签名应等价于如下:

bool cmp(const Type1 &a, const Type2 &b);

示例

#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
 
static bool abs_compare(int a, int b)
{
    return (std::abs(a) < std::abs(b));
}
 
int main()
{
    std::vector<int> v{ 3, 1, -14, 1, 5, 9 }; 
    std::vector<int>::iterator result;
 
    result = std::max_element(v.begin(), v.end());
    std::cout << "max element at: " << std::distance(v.begin(), result) << '\n';
 
    result = std::max_element(v.begin(), v.end(), abs_compare);
    std::cout << "max element (absolute) at: " << std::distance(v.begin(), result);
}

min

定义

template< class T > 
const T& min( const T& a, const T& b );

template< class T, class Compare >
const T& min( const T& a, const T& b, Compare comp );

template< class T >
T min( std::initializer_list<T> ilist );

template< class T, class Compare >
T min( std::initializer_list<T> ilist, Compare comp );

功能
  返回给定值中的较小者。

  • 1-2) 返回 ab 的较小者。
  • 3-4) 返回 initializer_list ilist 中值的最小者。
  • (1,3) 版本用 operator< 比较元素, (2,4) 版本用给定的比较函数 comp

参数

  • a, b - 要比较的值
  • ilist - 拥有要比较的值的 initializer_list
  • cmp - 比较函数对象(即满足比较 (Compare) 要求的对象),若 a 小于 b ,则返回 true

比较函数的签名应等价于如下:

bool cmp(const Type1 &a, const Type2 &b);

返回值

  • 1-2) ab 的较小者。若值等价,则返回 a
  • 3-4) ilist 中的最小值。若有数个等价于最小者的值,则返回最左侧的这种值。

警告
  若参数之一是右值,且返回该参数,则以引用捕获 std::min 的结果会产生一个悬垂引用:

int n = 1;
const int& r = std::min(n-1, n+1);
// r 为悬垂

示例

#include <algorithm>
#include <iostream>
#include <string>
 
int main()
{
    std::cout << "smaller of 1 and 9999: " << std::min(1, 9999) << '\n'
              << "smaller of 'a', and 'b': " << std::min('a', 'b') << '\n'
              << "shortest of \"foo\", \"bar\", and \"hello\": " <<
                  std::min( { "foo", "bar", "hello" },
                            [](const std::string& s1, const std::string& s2) {
                                 return s1.size() < s2.size();
                             }) << '\n';
}

输出

smaller of 1 and 9999: 1
smaller of 'a', and 'b': a
shortest of "foo", "bar", and "hello": foo

min_element

定义

template< class ForwardIt > 
ForwardIt min_element( ForwardIt first, ForwardIt last );

template< class ForwardIt, class Compare >
ForwardIt min_element( ForwardIt first, ForwardIt last, Compare comp );

功能
  寻找范围 [first, last) 中的最小元素。

1) 用 operator< 比较元素。
  2) 用给定的二元比较函数 comp 比较元素。

参数

  • first, last - 定义要检验范围的向前迭代器
  • comp - 比较函数对象(即满足比较 (Compare) 要求的对象),若a 小于 b ,则返回 true

比较函数的签名应等价于如下:

bool cmp(const Type1 &a, const Type2 &b);

返回值
  指向范围 [first, last) 中最小元素的迭代器。若范围中有多个元素等价于最小元素,则返回指向首个这种元素的迭代器。若范围为空则返回 last

示例

#include <algorithm>
#include <iostream>
#include <vector>
 
int main()
{
    std::vector<int> v{3, 1, 4, 1, 5, 9};
 
    std::vector<int>::iterator result = std::min_element(std::begin(v), std::end(v));
    std::cout << "min element at: " << std::distance(std::begin(v), result);
}

排列操作

定义于头文件 <algorithm>

next_permutation

定义

template< class BidirIt >
bool next_permutation( BidirIt first, BidirIt last );

template< class BidirIt, class Compare >
bool next_permutation( BidirIt first, BidirIt last, Compare comp );

功能
  变换范围 [first, last) 为来自所有按相对于 operator<comp 的字典序的下个排列。若这种排列存在则返回 true ,否则变换范围为首个排列(如同用 std::sort(first, last) )并返回 false

参数

  • first, last - 要重排的元素范围
  • comp - 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回 true

比较函数的签名应等价于如下:

bool cmp(const Type1 &a, const Type2 &b);

返回值
  若新排列按字典序大于旧者则为 true 。若抵达最后重排并重置范围为首个排列则为 false

示例
  下列代码打印字符串 “aba“ 的全部三种排列

#include <algorithm>
#include <string>
#include <iostream>
 
int main()
{
    std::string s = "aba";
    std::sort(s.begin(), s.end());
    do {
        std::cout << s << '\n';
    } while(std::next_permutation(s.begin(), s.end()));
}

prev_permutation

定义

template< class BidirIt >
bool prev_permutation( BidirIt first, BidirIt last);

template< class BidirIt, class Compare >
bool prev_permutation( BidirIt first, BidirIt last, Compare comp);

功能
  变换范围 [first, last) 为来自于相对于 operator<comp 的字典序的所有排列集合的上个排列。若这种排列存在则返回 true ,否则变换范围为末排列(如同用 std::sort(first, last); std::reverse(first, last); )并返回 false

返回值
  若新排列按字典序前趋旧排列则为 true 。若抵达首个排列并重置范围为最末排列则为 false

示例
下列代码以逆序打印字符串 “abc“ 的所有六个排列

#include <algorithm>
#include <string>
#include <iostream>
#include <functional>
int main()
{
    std::string s="abc";
    std::sort(s.begin(), s.end(), std::greater<char>());
    do {
        std::cout << s << ' ';
    } while(std::prev_permutation(s.begin(), s.end()));
    std::cout << '\n';
}
posted @ 2020-10-10 17:50  予之路  阅读(142)  评论(0编辑  收藏  举报