STL常用算法

std::adjacent_find:在序列中查找第一对相邻且值相等的元素;

std::find: 对一个输入序列,查找第一个等于给定值的元素;

std::find_end: 查找有B定义的序列在A序列中最后一次出现的位置(B可能是A的子序列);

std::find_first_of:查找A序列中第一个与序列B中任一元素值相等的元素位置;

std::find_if: 在序列中返回满足谓词(给定的条件)的第一个元素;

std::find_if_not:在序列中返回不满足谓词的第一个元素;

std::all_of: 如果序列中所有元素均满足给定的条件,则返回true;

std::any_of: 如果序列中存在元素满足给定的条件,则返回true;

std::none_of: 如果序列中所有元素均不满足给定的条件,则返回true;

std::binary_search:对一个升序序列做二分搜索,判断序列中是否有与给定值相等的元素;

std::search: 在序列A中,搜索B首次出现的位置(B可能是A的子序列);

std::search_n: 在给定序列中,搜索给定值连续出现n次的位置;

std::copy: 将一个序列中的元素拷贝到新的位置;

std::copy_backward:把一个序列复制到另一个序列,按照由尾到头顺序依次复制元素;

std::copy_if: 将一个序列中满足给定条件的元素拷贝到新的位置;

std::copy_n: 将一个序列中的前n个元素拷贝到新的位置;

std::count: 返回序列中等于给定值元素的个数;

std::count_if: 返回序列中满足给定条件的元素的个数;

std::equal: 比较两个序列的对应元素是否相等;

std::equal_range:在已排序的序列中,查找元素等于给定值组成的子范围;

std::lower_bound:在升序的序列中,查找第一个不小于给定值的元素;

std::upper_bound:在已排序的序列中,查找第一个大于给定值的元素;

std::fill: 用给定值填充序列中的每个元素;

std::fill_n: 用给定值填充序列中的n个元素;

std::for_each: 将指定函数应用于范围内的每一个元素;

std::generate: 对序列中的每个元素,用依次调用函数gen的返回值赋值;

std::generate_n:对序列中的n个元素,用依次调用指定函数gen的返回值赋值;

std::includes: 判断第二个已排序的序列是否全部都出现在第一个已排序的序列中;

std::inplace_merge:对两个升序的序列执行原地合并,合并后的序列仍保持升序;

std::merge: 对两个升序的序列合并,结果序列保持升序;

std::is_heap: 判断序列是否为二叉堆;

std::is_heap_until:查找第一个不是堆顺序的元素;

std::make_heap: 对于一个序列,构造一个二叉堆;

std::pop_heap: 堆的根节点被移除,堆的元素数目减1并保持堆性质;

std::push_heap: 向堆中增加一个新元素,新元素最初保存在last-1位置;

std::sort_heap: 对一个堆,执行原地堆排序,得到一个升序结果;

std::is_partitioned:判断序列是否按指定谓词划分过;

std::partition: 对序列重排,使得满足谓词的元素位于最前;

std::partition_copy:输入序列中,满足谓词的元素复制到result_true,其它元素复制到result_false;

std::partition_point:输入序列已经是partition,折半查找到分界点;

std::stable_partiton:对序列重排,使得满足谓词的元素在前,不满足谓词的元素在后,且两组元素内部的相对顺序不变;

std::is_permutation:判断两个序列是否为同一元素的两个排列;

std::next_permutation:n个元素有n!中排列。这些排列中,规定升序序列为最小排列,降序序列为最大的排列,任意两个排列按照字典序分出大小。该函数返回当前序列作为一个排列按字典序的下一个排列;

std::prev_permutation:返回当前序列作为一个排列按字典序的上一个排列;

std::is_sorted: 判断序列是否为升序;

std::is_sorted_until:查找序列中第一个未排序的元素;

std::nth_element:对序列重排,使得指定的位置出现的元素就是有序情况下应该在该位置出现的那个元素,且在指定位置之前的元素都小于指定位置元素,在指定位置之后的元素都大于指定位置元素;

std::partial_sort:对序列进行部分排序;

std::partial_sort_copy:拷贝部分排序的序列;

std::sort: 对序列进行排序;

std::stable_sort:对序列进行稳定排序;

std::iter_swap: 交换两个迭代器指向的元素;

std::swap: 交换两个对象,优先使用移动语义;

std::swap_ranges:交换两个序列中对应元素;

std::lexicographical_compare:对两个序列做字典比较,如果第一个序列在字典序下小于第二个序列,则返回true;

std::min: 返回两个值中的最小值;

std::min_element:返回序列中的最小值;

std::max: 返回两个值中的最大值;

std::max_element:返回序列中的最大值;

std::minmax: 返回由最小值与最大值构成的std::pair;

std::minmax_element:返回由序列中最小元素与最大元素构成的std::pair;

std::mismatch: 比较两个序列的对应元素,返回用std::pair表示的第一处不匹配在两个序列的位置;

std::move: 把输入序列中的逐个元素移动到结果序列;注意与   http://blog.csdn.net/fengbingchun/article/details/52558914 中的不同;

std::move_backward:把输入序列中的逐个元素自尾到头移动到结果序列;

std::shuffle: 使用均匀随机数生成器,随机打乱指定范围中的元素的位置;

std::random_shuffle:n个元素有!n个排列,该函数给出随机选择的一个排列;

std::remove: 删除序列中等于给定值的所有元素;

std::remove_if: 删除序列中满足给定谓词的元素;

std::remove_copy:把一个序列中不等于给定值的元素复制到另一个序列中;

std::remove_copy_if:把一个序列中不满足给定谓词的元素复制到另一个序列中;

std::replace: 把序列中等于给定值的元素替换为新值;

std::replace_if:把序列中满足给定谓词的元素替换为新值;

std::replace_copy:拷贝序列,对于等于老值的元素复制时使用新值;

std::replace_copy_if:拷贝序列,对于满足给定谓词的元素复制时使用新值;

std::reverse: 把序列中的元素逆序;

std::reverse_copy:拷贝序列的逆序到另一个序列中;

std::rotate: 等效于循环左移序列,使得迭代器middle所指的元素成为首元素;

std::rotate_copy:等效于循环左移序列并拷贝到新的序列中,使得迭代器middle所指的元素成为首元素;

std::set_difference:两个升序序列之差;

std::set_intersection:两个升序序列的交;

std::set_symmetric_difference:两个升序序列的对称差;

std::set_union: 两个升序序列的并;

std::transform: 对序列中的每一个元素,执行一元操作,结果写入另一序列中;或对两个序列中对应的每一对元素,执行二元操作,结果写入另一序列中;

std::unique: 对序列中一群连续的相等的元素,仅保留第一个元素;

std::unique_copy:把一个序列中的元素拷贝到另一个序列,对于一群连续的相等的元素,仅拷贝第一个元素。

 

 

 

 

 

 

std::find()

对一个输入序列,查找第一个等于给定值的元素

std::vector<int> numbers {5, 46, -5, -6, 23, 17, 5, 9, 6, 5};
int value {23};
auto iter = std::find(std::begin(numbers), std::end(numbers), value);
if (iter != std:: end (numbers))
    std::cout << value << " was found. \n";

std::find_if()

在序列中返回满足谓词(给定的条件)的第一个元素

typedef struct testStruct
{
	int a;

	int b;
}testStruct;

int main()
{
	std::vector<testStruct> testStructVector{ {1, 2}, {3, 4}, {8, 8} };
	auto iterFind = std::find_if(testStructVector.begin(), testStructVector.end(), [](const testStruct& myStruct)
	{
		return myStruct.a > 2 && myStruct.b < 8;
	});
	if (iterFind != testStructVector.end())
		std::cout << iterFind->a << "  " << iterFind->b << std::endl;
	else
		std::cout << "no find" << std::endl;
}

find_if_not()

find_if_not() 函数和 find_if() 函数的功能恰好相反,通过上面的学习我们知道,find_if() 函数用于查找符合谓词函数规则的第一个元素,而 find_if_not() 函数则用于查找第一个不符合谓词函数规则的元素。

#include <iostream>     // std::cout
#include <algorithm>    // std::find_if_not
#include <vector>       // std::vector
using namespace std;
//自定义一元谓词函数
bool mycomp(int i) {
    return ((i % 2) == 1);
}

int main() {
    vector<int> myvector{4,2,3,1,5};
    //调用 find_if() 函数,并以 mycomp() 一元谓词函数作为查找规则
    vector<int>::iterator it = find_if_not(myvector.begin(), myvector.end(), mycomp);
    cout << "*it = " << *it;
    return 0;
}

adjacent_find()

adjacent_find() 算法可以用来搜索序列中两个连续相等的元素。用 == 运算符来比较连续的一对元素,返回的迭代器指向前两个相等元素中的第一个。如果没有一对相等的元素,这个算法返回这个序列的结束迭代器。

string saying {"Children should be seen and not heard."};
auto iter = std::adjacent_find(std::begin(saying), std::end(saying));
if (iter != std::end(saying))
    std::cout <<"In the following text: \n\""<< saying << "\"\n'"<< *iter << "' is repeated starting at index position "<< std::distance(std::begin(saying), iter) << std::endl;

//输出
/*
In the following text:
"Children should be seen and not heard."
'e' is repeated starting at index position 20
*/
	std::vector<long> numbers{ 64L, 46L, -65L, -128L, 121L, 17, 35L, 9L, 91L, 5L };
	auto iter = std::adjacent_find(std::begin(numbers), std::end(numbers), [](long n1, long n2) 
	{
		return n1 % 2 && n2 % 2; 
	});
    
//连续的2个奇数
	if (iter != std::end(numbers))
		std::cout << "The first pair of odd numbers is " << *iter << " and " << *(iter + 1) << std::endl;

std::find_end()

find_end() 会在一个序列中查找最后一个和另一个元素段匹配的匹配项,也可以看作在一个元素序列中查找子序列的最后一个匹配项。这个算法会返回一个指向子序列的最后一个匹配项的第一个元素的迭代器,或是一个指向这个序列的结束迭代器。

	std::string text{ "had had test had had hello" };
	std::cout << text << std::endl;
	std::string phrase{ "had had" };
	auto iter = std::find_end(std::begin(text), std::end(text), std::begin(phrase), std::end(phrase));
	if (iter != std::end(text))
		std::cout << "The last \"" << phrase << "\" was found at index " << std::distance(std::begin(text), iter) << std::endl;

std::find_first_of()

	const char* strOne = "abcdef1212daxs";
	const char* strTwo = "2ef";

	const char* result = std::find_first_of(strOne, strOne + strlen(strOne),
		strTwo, strTwo + strlen(strTwo));

	std::cout << "字符串strOne中第一个出现在strTwo的字符为:" << *result << std::endl;

std::count()

返回序列中等于给定值元素的个数

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
    int n;
    vector <int> V;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int temp;
        cin>>temp;
        V.push_back(temp);
    }
    int ask;
    while(cin>>ask)
    {
        int num=count(V.begin(),V.end(),ask);
        cout<<num<<endl;
    }
    return 0;
}

std::count_if ()

返回序列中满足给定条件的元素的个数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
struct student
{
    string name;
    int score;
};
bool compare(student a)
{
    return 90<a.score;
}
int main()
{
    int n;
    cin>>n;
    vector<student> V;
    for(int i=0;i<n;i++)
    {
        student temp;
        cin>>temp.name>>temp.score;
        V.push_back(temp);
    }
    cout<<count_if(V.begin(),V.end(),compare)<<endl;
    return 0;
}

sort (first, last)

对容器或普通数组中 [first, last) 范围内的元素进行排序,默认进行升序排序。

//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

is_sorted()

检查数组或者向量是否被排序好

is_sorted(a,a+5);
is_sorted(v.begin(),v.end());//默认升序检查

is_sorted(a,a+5,greater<int>());
is_sorted(v.begin(),v.end(),greater<int>());//降序检查

bool cmp(const int & a, const int & b){
  return a%10>b%10; 
} 

is_sorted(a,a+5,cmp);
is_sorted(v.begin(),v.end(),cmp);//自定义排序规则

stable_sort()

stable_sort()可以对vector的某个成员进行排序,而且可保证相等元素的原本相对次序在排序后保持不变

#include <iostream>
#include<math.h>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
 
using namespace std;
 
typedef struct TagNode
{
	int value;
	int index;
}Node;
 
bool myCmp(const Node& a, const Node& b)
{
	return a.value < b.value;
}
int main(int argc, char **argv)
{
	vector<Node> vtNode;
	vtNode.clear();
	Node tmp;
	int idx = 0, num;
 
	while(cin >> num && num)
	{
		++idx;
		tmp.value = num;
		tmp.index = idx;
		vtNode.push_back(tmp);
	}
 
	stable_sort(vtNode.begin(), vtNode.end(), myCmp);
 
	cout << "Index\tValue:" << endl;
	vector<Node>::iterator pos;
	for(pos = vtNode.begin(); pos != vtNode.end(); ++pos)
	{
		cout << pos->index << "\t" << pos->value << endl;
	}
	return 0;
}

search 

ForwardIterator1 search (ForwardIterator1 beg, ForwardIterator1 end,ForwardIterator2 searchBeg, ForwardIterator2 searchEnd);

ForwardIterator1search (ForwardIterator1 beg, ForwardIterator1 end,ForwardIterator2 searchBeg, ForwardIterator2 searchEnd,BinaryPredicate op);

  1. 第一种形式,查找第一个区间与第二个区间完全一致的第一个子区间,如果找到则返回子区间的第一个位置。
  2. 第二种形式,查找第一个区间与第二个区间使op全部返回true 的子区间,如果找到则返回子区间的第一个位置。
  3. op在函数执行过程中,不应该改变元素的内容也不应该op的状态。
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <functional>
#include <list>
using namespace std;
 
bool checkOdd(int n,bool b)
{
    if (b)
    {
	return n % 2 == 0;
    }
    else
    {
	return n % 2 == 1;
    }
}
 
int main()
{
    vector<int>v{ 1,2,3,4,5,6,7,8,9,6,5,4,1,2,3,4,5 };
    list<int>lst{ 3,4,5 };
 
    auto pos1 = search(v.begin(), v.end(), lst.begin(),lst.end());
 
    while (pos1 != v.end())
    {
	cout << distance(v.begin(), pos1) << ends;
	pos1++;
	pos1 = search(pos1, v.end(), lst.begin(), lst.end());
    }
 
    cout << endl;
    bool bl[3] = {true,false,true};
    auto pos2 = search(v.begin(), v.end(), bl, bl + 3, checkOdd);
    while (pos2 = v.end())
    {
	cout << distance(v.begin(), pos2) << ends;
	pos2 ++;
	pos2 = search(pos2, v.end(), bl, bl + 3, checkOdd);
    }
 
    return 0;
}
 
/*输出结果:2 14
           1 3 5 7 9 11 13
*/

 

std::search_n

std::search_n查找区间内连续n个满足某一条件或者等于某一值的情况,并返回满足条件的第一个元素位置。

ForwardIterator search_n (ForwardIterator beg, ForwardIterator end,Size count, const T& value);

ForwardIterator search_n (ForwardIterator beg, ForwardIterator end,Size count, const T& value, BinaryPredicate op);

  1. 第一种形式返回区间内,连续count个元素都等于value的第一个元素的位置。第二种形式返回连续count个元素都使op返回true的第一个元素的位置。如果没有满足条件的情况,两种形式都返回end位置。
  2. op操作不应改变传入的参数,并且在函数调用状态过程中不能改变op的状态。
  3. 该函数的第一种形态很好理解,但是第二种形态却有点让人很不舒服。该算法不在早期STL规范中,也没有被严谨对待,因此第二种形式与我们常见的STL算法很不相同,其中op是一个二元谓语(接受两个参数)而不是一元谓语
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main()
{
    vector<int>v1{1,1,2,3,4,4,4,5,6,7,8,9};
 
    auto it0 = search_n(v1.begin(), v1.end(), 3, 4);//查找连续三个==4的数
 
    if (it0 != v1.end())
    {
	cout << distance(v1.begin(), it0)<<endl;
    }
    //其中search_n的第四个参数对应着lambda表达式中的第二个参数,在这里我们没有实际作用。
    auto it1 = search_n(v1.begin(), v1.end(), 3, 0, [](int n, int) {return n > 4;});
    if (it1 != v1.end())
    {
	cout << distance(v1.begin(), it1) << endl;
    }
 
    //auto it2 = search_n(v1.begin(), v1.end(), 3, 0, [](int n) {return n > 3;});//错误,编译错误
	
    /*查找连续三个小于5的数,less<T>接受两个参数,如果第一个参数小于第二个则返回true,
    否则返回false,通过这里,我们也就明白为什么最开始设计的时候最后一个参数为什么接受两个参数而不是一个参数了。*/
    auto it3 = search_n(v1.begin(), v1.end(), 3, 5, less<int>());
    if (it3 != v1.end())
    {
	cout << distance(v1.begin(), it3) << endl;
    }
    return 0;
}
 
/*输出结果: 4
           7
           0  
*/

std::binary_search()

大家都知道,二分查找是在排序后的基础上来对其进行查找操作。所以在使用bianry_search的时候,需要将要查找的容器进行排序。

说明

在这里说明两种,一种是对结构体的二分操作,一种是对数组进行二分操作,在操作之前,肯定是需要对结构体进行排序,如何排序,这里就用到了STL里面很实用的sort函数。

特别强调:排序的必须是从小到大

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector <int> V;
int main()
{
    V.push_back(2);
    V.push_back(3);
    V.push_back(1);
    sort(V.begin(), V.end());//对vector 的排序
    if(binary_search(V.begin(), V.end(), 2)) // 对vector进行二分查找
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    return 0;
}

std::all_of()

如果序列中所有元素均满足给定的条件,则返回true

std::any_of()

如果序列中存在元素满足给定的条件,则返回true

none_of()

算法会返回 true,前提是序列中没有元素可以使谓词返回 true

std::vector<int> ages {22, 19, 46, 75, 54, 19, 27, 66, 61, 33, 22, 19};
int min_age{18};
std::cout << "There are "<< (std::none_of(std::begin(ages), std::end(ages),[min_age](int age) { return age < min_age; }) ? "no": "some") << " people under " << min_age << std::endl;

std::cout << "There are "<< (std::any_of(std::begin(ages), std::end(ages),[min_age] (int age) { return age < min_age;}) ? "some":"no") <<" people under " << min_age << std::endl;

int good_age{100};
std::cout << (std::all_of(std::begin(ages), std::end(ages),[good_age] (int age) { return age < good_age; }) ? "None": "Some") << " of the people are centenarians." << std::endl;

std::transform()

以下是std::transform的两个声明,一个是对应于一元操作,一个是对应于二元操作

template <class InputIterator, class OutputIterator, class UnaryOperation>
  OutputIterator transform (InputIterator first1, InputIterator last1,
                            OutputIterator result, UnaryOperation op);
	
template <class InputIterator1, class InputIterator2,
          class OutputIterator, class BinaryOperation>
  OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
                            InputIterator2 first2, OutputIterator result,
                            BinaryOperation binary_op);
#include "transform.hpp"
#include <algorithm> // std::transform
#include <string>
#include <cctype> // std::toupper
#include <iostream>
#include <vector>
#include <functional> // std::plus c++14
 
int test_transform1()
{
	std::string s("Hello");
	std::transform(s.begin(), s.end(), s.begin(),
		[](unsigned char c) { return std::toupper(c); });
	std::cout << s << std::endl; // HELLO
 
	std::transform(s.begin(), s.end(), s.begin(), ::tolower);
	std::cout << s << std::endl; // hello

	std::vector<int> arr{ 1, 3, 5 };
	std::vector<int> arr2{ 1, 3, 5 };
	std::vector<int> arr3{ 1, 3, 5 };
 
	std::transform(arr.begin(), arr.end(), arr.begin(),
		[](int d) -> int {return d * 5; }); // for_each
	for (auto value : arr) {
		std::cout << value << "    "; // 5 15 25
	}
	std::cout<<std::endl;
 
	std::for_each(arr2.begin(), arr2.end(), [](int& a) {a *= 5; });
	for (auto value : arr2) {
		std::cout << value << "    "; // 5 15 25
	}
	std::cout << std::endl;
 
	for (auto& value : arr3) {
		value *= 5;
	}
	for (auto value : arr3) {
		std::cout << value << "    "; // 5 15 25
	}
	std::cout << std::endl;
 
	std::vector<std::string> names = { "hi", "test", "foo" };
	std::vector<std::size_t> name_sizes;
 
	///
	std::transform(names.begin(), names.end(), std::back_inserter(name_sizes),
		[](std::string name) { return name.size(); });
	for (auto value : name_sizes) {
		std::cout << value << "    "; // 2 4 3
	}
	std::cout << std::endl;
 
	std::for_each(name_sizes.begin(), name_sizes.end(), [](std::size_t name_size) {
		std::cout << name_size << "    "; // 2 4 3
	});
	std::cout << std::endl;
 
	return 0;
}
 
/
// reference: http://www.cplusplus.com/reference/algorithm/transform/
static int op_increase(int i) { return ++i; }
 
int test_transform2()
{
	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; // 21 41 61 81 101
	std::cout << '\n';
 
	return 0;
}
 

std::remove()

删除序列中等于给定值的所有元素

#include <algorithm>
#include <string>
#include <iostream>
#include <cctype>
  
int main()
{
    std::string str1 = "Text with some   spaces 123";
    std::remove(str1.begin(), str1.end(), ' ');
    std::cout << str1 << '\n';
}

std::remove_if()

删除序列中满足给定谓词的元素

	std::string str = "Hello, World!";
	cout << str << endl;

	std::remove_if(str.begin(), str.end(), [](char c) { return c == 'W'; });
	cout << str << endl;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值