1. 程式人生 > >STL常用演算法

STL常用演算法

簡介

STL演算法部分主要由標頭檔案, , 組成。要使用STL中的演算法函式,必須包含標頭檔案,對於數值演算法必須包含。中則定義了一些模板類,用來宣告函式物件(又名仿函式)。 STL中演算法大致分為四類:

  • 不改變序列演算法:指不直接修改其所操作的容器內容的演算法。
  • 改變序列演算法:指可以修改它們所操作的容器內容的演算法。
  • 排序演算法:包括對序列進行排序和合並的演算法、搜尋演算法以及有序序列上的集合操作。
  • 數值演算法:對容器內容進行數值計算。

演算法彙總

標*號的為C++11引入。

  • 不改變序列演算法
名稱 功能
all_of * 測試序列中的所有元素是否都滿足條件
any_of * 測試序列中是否有元素滿足條件
none_of * 測試序列中的所有元素是否都不滿足條件
for_each 在整個序列上應用函式
find 在序列中查詢值
find_if 在序列中查詢元素
find_if_not * 在序列中查詢不滿足條件的元素
find_end 在序列中查詢最後匹配的子序列
find_first_of 在序列中查詢第一個和集合匹配的元素
adjacent_find 在序列中查詢相鄰且相等的元素
count 計算序列某值出現的次數
count_if 計算序列中滿足條件的元素個數
mismatch 返回兩個序列中元素不相等的首位置
equal 測試兩個序列中的元素值是否相等
is_permutation * 測試一個序列是否是另一個序列的排列
search 搜尋子序列在序列中出現的位置
search_n 在序列中搜索某值連續出現n次的位置
  • 改變序列演算法:
名稱 功能
copy 複製序列
copy_n * 複製n個元素
copy_if * 複製序列內滿足條件的元素
copy_backward 從後往前複製元素
move * 移動序列內的元素
move_backward * 從後往前移動序列內的元素
swap 交換兩個物件的值
swap_ranges 交換兩個序列的值
iter_swap 交換兩個迭代器所指向的值
transform 序列變換
replace 將序列中的舊值替換為新值
replace_if 將序列中滿足條件的值替換為新值
replace_copy 複製序列,並將舊值替換為新值
replace_copy_if 複製序列,並將滿足條件的值替換為新值
fill 用固定值填充序列
fill_n 用固定值填充序列
generate 用生成函式生成序列
generate_n 用生成函式生成序列
remove 從原序列中移除特定值的元素
remove_if 從原序列中移除滿足條件的元素
remove_copy 從原序列複製到新序列,且不包含原序列中特定值元素
remove_copy_if 從原序列複製到新序列,且不包含原序列中滿足特定條件的元素
unique 剔除序列中連續重複的元素
unique_copy 從原序列複製到新序列,且不包含原序列中連續重複的元素
reverse 序列反轉
reverse_copy 序列複製反轉
rotate 序列左邊和序列右邊的元素交換
rotate_copy 在新序列中將原序列左邊和右邊的元素互換
random_shuffle 對容器內的元素進行隨機重排
shuffle * 對容器內的元素進行隨機重排
  • 分割演算法:
名稱 功能
is_partitioned * 測試序列是否已分割
partition 根據給定條件將序列中的元素分割
stable_partition 根據給定條件將序列中的元素穩定分割
partition_copy * 根據給定條件將序列複製分割為兩個序列
partition_point * 返回序列內第一個不符合條件的迭代器
  • 排序演算法:
名稱 功能
sort 排序
stable_sort 穩定排序
partial_sort 區域性排序(用於挑選最大/最小的若干元素)
partial_sort_copy 區域性排序到另一個序列
is_sorted * 檢查序列是否已排序
is_sorted_until * 返回第一個未排序的元素的迭代器
nth_element 將第n個元素排序到合適的位置
  • 二分搜尋(作用於已排序序列):
名稱 功能
lower_bound 下确界,在有序序列中查詢首個不小於某值的元素
upper_bound 上確界,在有序序列中查詢首個不大於某值的元素
equal_range 等區間,在有序序列中和某值相等的區間
binary_search 測試某值在有序序列中是否存在
  • 歸併演算法 (作用於已排序序列):
名稱 功能
merge 合併有序序列
inplace_merge 將一個序列內部兩個已排序的子序列合併
includes 檢測一個有序序列是否包含另一個有序序列,相當於集合中的包含關係
set_union 集合求並
set_intersection 集合求交
set_difference 集合求差(屬於集合S1但不屬於集合S2)
set_symmetric_difference 集合求對稱差集(屬於S1但不屬於S2以及屬於S2但不屬於S1)
  • 堆演算法:
名稱 功能
push_heap 向堆中插入一個元素
pop_heap 從堆中彈出一個元素
make_heap 將序列重排為一個堆序列
sort_heap 將堆序列中的元素排序
is_heap * 測試一個序列是否為堆序列
is_heap_until * 找出序列中第一個不滿足堆序列規則的元素
  • 最大值/最小值演算法:
名稱 功能
min 求最小值
max 求最大值
minmax * 求最小最大值
min_element 返回序列中的最小元素
max_element 返回序列中的最大元素
minmax_element * 求序列中的最小最大元素
  • 其它:
名稱 功能
lexicographical_compare 字典比較兩個序列
next_permutation 對序列進行一次排序,使之字典順序大於原來的排列
prev_permutation 對序列進行一次排序,使之字典順序小於原來的排列
  • 數值演算法:
名稱 功能
accumulate 將序列元素進行累計求和
adjacent_difference 求序列相鄰元素之差
inner_product 求兩序列元素內積
partial_sum 求序列部分和
iota * 儲存遞增序列

函式原型及功能

  • 不改變序列演算法
// all_of 原型
template <class InputIterator, class UnaryPredicate>
	bool all_of (InputIterator first, InputIterator last, UnaryPredicate pred);

// 行為
template<class InputIterator, class UnaryPredicate>
	bool all_of (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (!pred(*first)) return false;
    ++first;
  }
  return true;
}


// any_of 原型
template <class InputIterator, class UnaryPredicate>
  bool any_of (InputIterator first, InputIterator last, UnaryPredicate pred);

// 行為
template<class InputIterator, class UnaryPredicate>
  bool any_of (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return true;
    ++first;
  }
  return false;
}


// none_of 原型
template <class InputIterator, class UnaryPredicate>
  bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred);

// 行為
template<class InputIterator, class UnaryPredicate>
  bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return false;
    ++first;
  }
  return true;
}


// for_each 原型
template <class InputIterator, class Function>
   Function for_each (InputIterator first, InputIterator last, Function fn);

// 行為
template<class InputIterator, class Function>
  Function for_each(InputIterator first, InputIterator last, Function fn)
{
  while (first!=last) {
    fn (*first);
    ++first;
  }
  return fn;      // or, since C++11: return move(fn);
}


// find 原型
template <class InputIterator, class T>
   InputIterator find (InputIterator first, InputIterator last, const T& val);

// 行為
template<class InputIterator, class T>
  InputIterator find (InputIterator first, InputIterator last, const T& val)
{
  while (first!=last) {
    if (*first==val) return first;
    ++first;
  }
  return last;
}


// find_if 原型
template <class InputIterator, class UnaryPredicate>
   InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);

// 行為
template<class InputIterator, class UnaryPredicate>
  InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}

// find_if_not 原型
template <class InputIterator, class UnaryPredicate>
   InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred);

// 行為
template<class InputIterator, class UnaryPredicate>
  InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (!pred(*first)) return first;
    ++first;
  }
  return last;
}


// find_end 原型
template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator2 last2);  // 版本1
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                              ForwardIterator2 first2, ForwardIterator2 last2,
                              BinaryPredicate pred);  // 版本2

// 行為
template<class ForwardIterator1, class ForwardIterator2>
  ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2)
{
  if (first2==last2) return last1;  // specified in C++11

  ForwardIterator1 ret = last1;

  while (first1!=last1)
  {
    ForwardIterator1 it1 = first1;
    ForwardIterator2 it2 = first2;
    while (*it1==*it2) {    // or: while (pred(*it1,*it2)) for version (2)
        ++it1; ++it2;
        if (it2==last2) { ret=first1; break; }
        if (it1==last1) return ret;
    }
    ++first1;
  }
  return ret;
}


// find_first_of 原型
template <class InputIterator, class ForwardIterator>
   InputIterator find_first_of (InputIterator first1, InputIterator last1,
                                   ForwardIterator first2, ForwardIterator last2);  // 版本1
template <class InputIterator, class ForwardIterator, class BinaryPredicate>
   InputIterator find_first_of (InputIterator first1, InputIterator last1,
                                   ForwardIterator first2, ForwardIterator last2,
                                   BinaryPredicate pred);  // 版本2

// 行為
template<class InputIterator, class ForwardIterator>
  InputIterator find_first_of ( InputIterator first1, InputIterator last1,
                                ForwardIterator first2, ForwardIterator last2)
{
  while (first1!=last1) {
    for (ForwardIterator it=first2; it!=last2; ++it) {
      if (*it==*first1)          // or: if (pred(*it,*first)) for version (2)
        return first1;
    }
    ++first1;
  }
  return last1;
}


// adjacent_find 原型
template <class ForwardIterator>
   ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last);  // 版本1
template <class ForwardIterator, class BinaryPredicate>
   ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last,
                                  BinaryPredicate pred);  // 版本2

// 行為
template <class ForwardIterator>
   ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
{
  if (first != last)
  {
    ForwardIterator next=first; ++next;
    while (next != last) {
      if (*first == *next)     // or: if (pred(*first,*next)), for version (2)
        return first;
      ++first; ++next;
    }
  }
  return last;
}


// count 原型
template <class InputIterator, class T>
  typename iterator_traits<InputIterator>::difference_type
    count (InputIterator first, InputIterator last, const T& val);

// 行為
template <class InputIterator, class T>
  typename iterator_traits<InputIterator>::difference_type
    count (InputIterator first, InputIterator last, const T& val)
{
  typename iterator_traits<InputIterator>::difference_type ret = 0;
  while (first!=last) {
    if (*first == val) ++ret;
    ++first;
  }
  return ret;
}


// count_if 原型
template <class InputIterator, class UnaryPredicate>
  typename iterator_traits<InputIterator>::difference_type
    count_if (InputIterator first, InputIterator last, UnaryPredicate pred);

// 行為
template <class InputIterator, class UnaryPredicate>
  typename iterator_traits<InputIterator>::difference_type
    count_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  typename iterator_traits<InputIterator>::difference_type ret = 0;
  while (first!=last) {
    if (pred(*first)) ++ret;
    ++first;
  }
  return ret;
}


// mismatch 原型
template <class InputIterator1, class InputIterator2>
  pair<InputIterator1, InputIterator2>
    mismatch (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2);  // 版本1
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
  pair<InputIterator1, InputIterator2>
    mismatch (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, BinaryPredicate pred);  // 版本2

// 行為
template <class InputIterator1, class InputIterator2>
  pair<InputIterator1, InputIterator2>
    mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
{
  while ( (first1!=last1) && (*first1==*first2) )  // or: pred(*first1,*first2), for version 2
  { ++first1; ++first2; }
  return std::make_pair(first1,first2);
}


// equal 原型
template <class InputIterator1, class InputIterator2>
  bool equal (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2);  // 版本1
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
  bool equal (InputIterator1 first1, InputIterator1 last1,
              InputIterator2 first2, BinaryPredicate pred);  // 版本2

// 行為
template <class InputIterator1, class InputIterator2>
  bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
{
  while (first1!=last1) {
    if (!(*first1 == *first2))   // or: if (!pred(*first1,*first2)), for version 2
      return false;
    ++first1; ++first2;
  }
  return true;
}


// is_permutation 原型
template <class ForwardIterator1, class ForwardIterator2>
   bool is_permutation (ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2);  // 版本1
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   bool is_permutation (ForwardIterator1 first1, ForwardIterator1 last1,
                        ForwardIterator2 first2, BinaryPredicate pred);  // 版本2

// 行為
template <class InputIterator1, class InputIterator2>
  bool is_permutation (InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2)
{
  std::tie (first1,first2) = std::mismatch (first1,last1,first2);
  if (first1==last1) return true;
  InputIterator2 last2 = first2; std::advance (last2,std::distance(first1,last1));
  for (InputIterator1 it1=first1; it1!=last1; ++it1) {
    if (std::find(first1,it1,*it1)==it1) {
      auto n = std::count (first2,last2,*it1);
      if (n==0 || std::count (it1,last1,*it1)!=n) return false;
    }
  }
  return true;
}


// search 原型
template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2);  // 版本1
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
   ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2,
                            BinaryPredicate pred);  // 版本2

// 行為
template<class ForwardIterator1, class ForwardIterator2>
  ForwardIterator1 search ( ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2)
{
  if (first2==last2) return first1;  // specified in C++11
  
  while (first1!=last1)
  {
    ForwardIterator1 it1 = first1;
    ForwardIterator2 it2 = first2;
    while (*it1==*it2) {    // or: while (pred(*it1,*it2)) for version 2
        if (it2==last2) return first1;
        if (it1==last1) return last1;
        ++it1; ++it2;
    }
    ++first1;
  }
  return last1;
}


// search_n 原型
template <class ForwardIterator, class Size, class T>
   ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
                             Size count, const T& val);  // 版本1
template <<