STL(一) 算法小技巧集锦

1、打印

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test_print()
{
	std::cout << "打印" << std::endl;
	std::vector<int> vec{1,2,3,4,6,8,4,0,20};
	std::for_each(vec.begin(),vec.end(),[](auto& e){ std::cout << e << " ";});
	std::cout << std::endl;    //  1 2 3 4 6 8 4 0 20

	std::copy(vecList.begin(), vecList.end(), std::ostream_iterator<int>(cout, ", "));
	cout << endl;             //  1 2 3 4 6 8 4 0 20
}

int main()
{
	test_print();
	return 0;
}

2、排序

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> 
using namespace std;

void test_print()
{
	std::cout << "排序" << std::endl;
	std::vector<int> vecList{1,2,3,4,6,8,4,0,20};
	
	std::cout << "从小到大排序:" << std::endl;
	std::sort(begin(vecList), end(vecList));
	std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
	cout << endl;       // 0 1 2 3 4 4 6 8 20
		
    std::cout << "从大到小排序:" << std::endl;
    std::sort(begin(vecList), end(vecList), std::greater<int>());
    std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
	cout << endl;       // 20 8 6 4 4 3 2 1 0
}

int main()
{
	test_print();
	return 0;
}

3、删除特定元素

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test_print()
{
	std::cout << "删除特定元素" << std::endl;
	std::vector<int> vecList{1,2,3,4,6,8,4,0,20};
	vecList.erase(std::remove(vecList.begin(), vecList.end(), 1), vecList.end());
	std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
	cout << endl;       // 2 3 4 6 8 4 0 20
}

int main()
{
	test_print();
	return 0;
}

4、去重

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test_print()
{
	std::cout << "去重" << std::endl;
	std::vector<int> vecList{1,2,3,4,6,8,4,0,20,1,4};
	vecList.erase(std::unique(vecList.begin(), vecList.end()), vecList.end());
	std::for_each(vecList.begin(), vecList.end(), [](auto& e) {cout << e << " "; });
	cout << endl;       // 1 2 3 4 6 8 0 20
}

int main()
{
	test_print();
	return 0;
}

5、std::all_of

  • std::all_of:检查区间[first, last)中是否所有的元素都满足一元判断式p,所有的元素都满足条件返回true,否则返回false。
  • std::all_of源码
// all_of 源码
template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 bool all_of(_InIt _First, _InIt _Last, _Pr _Pred) { // test if all elements satisfy _Pred
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        if (!_Pred(*_UFirst)) {
            return false;
        }
    }

    return true;
}
// 当传入容器为空,返回true
  • 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test()
{
	vector<int> v = { 1, 3, 5, 7, 9 };
	auto isEven = [](int i) {return i % 2 != 0; };
	bool isallOdd = std::all_of(v.begin(), v.end(), isEven);   // 注意:当v为空时,返回true
	if (isallOdd)
		cout << "all is odd" << endl;
}
int main()
{
	test();
	return 0;
}

6、std::none_of

  • std::none_of:检查区间[first, last)中是否所有的元素都不满足一元判断式p,所有的元素都不满足条件返回true,否则返回false。
  • std::none_of源码
// none_of 源码
template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 bool none_of(const _InIt _First, const _InIt _Last, _Pr _Pred) {
    // test if no elements satisfy _Pred
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        if (_Pred(*_UFirst)) {
            return false;
        }
    }

    return true;
}
// 当传入容器为空,返回true
  • 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test()
{
	vector<int> v = { 1, 3, 5, 7, 9 };
	auto isEven = [](int i) {return i % 2 != 0; };
	bool isNoneEven = std::none_of(v.begin(), v.end(), isEven); // 注意:当v为空时,返回true
	if (isNoneEven)
		cout << "none is even" << endl;
}
int main()
{
	test();
	return 0;
}

7、std::any_of

  • std::any_of:检查区间[first, last)中是否至少有一个元素都满足一元判断式p,只要有一个元素满足条件就返回true,否则返回false。false。
  • std::any_of源码
// any_of 源码
template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 bool any_of(const _InIt _First, const _InIt _Last, _Pr _Pred) {
    // test if any element satisfies _Pred
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        if (_Pred(*_UFirst)) {
            return true;
        }
    }

    return false;
}
// 当传入容器为空,返回false
  • 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test()
{
	auto isEven = [](int i) {return i % 2 != 0; };
	vector<int> v1 = { 1, 3, 5, 7, 8, 9 };
	bool anyof = std::any_of(v1.begin(), v1.end(), isEven);    // 注意:当v1为空时,返回false
	if (anyof)
		cout << "at least one is even" << endl;
}
int main()
{
	test();
	return 0;
}

8、std::minmax_element

  • std::minmax_element :同时获取最大值和最小值的算法minmax_element
  • std::minmax_element 源码
// minmax_element 源码
template <class _FwdIt, class _Pr>
_NODISCARD constexpr pair<_FwdIt, _FwdIt> minmax_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred) {
    // find smallest and largest elements
    _Adl_verify_range(_First, _Last);
    const auto _Result = _Minmax_element_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pass_fn(_Pred));
    _Seek_wrapped(_Last, _Result.second);
    _Seek_wrapped(_First, _Result.first);
    return {_First, _Last};
}

template <class _FwdIt>
_NODISCARD constexpr pair<_FwdIt, _FwdIt> minmax_element(_FwdIt _First, _FwdIt _Last) {
    // find smallest and largest elements
    return _STD minmax_element(_First, _Last, less<>{});
}
  • 实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void test()
{
	auto isEven = [](int i) {return i % 2 != 0; };
	vector<int> v1 = { 1, 3, 5, 7, 8, 9 };
	// 同时获取最大值和最小值的算法minmax_element
	auto maxmin = minmax_element(v1.begin(), v1.end());
	cout << *maxmin.first  << " " << *maxmin.second << endl;
}
int main()
{
	test();
	return 0;
}

9、std::copy_if

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int test()
{
	std::vector<int> v1{ 1, 2, 3, 4, 5 }, v2(v1.size());

	auto it = std::copy_if(v1.begin(), v1.end(), v2.begin(), [](auto& i) { return (i % 2 == 1); });
	v2.resize(std::distance(v2.begin(), it));

	std::for_each(v2.begin(), v2.end(), [](auto& e) {cout << e << " "; });  // 1 3 5
	cout << endl;
	return 0;
}
int main()
{
	test();
	return 0;
}

10、std::iota()

此函数用于为数组分配连续值。此函数接受3个参数,即数组名称、大小和起始编号。

#include<iostream>
#include<numeric> // for iota()
using namespace std;

int main()
{
	// Initializing array with 0 values
	int ar[6] = {0};

	// Using iota() to assign values
	iota(ar, ar+6, 20);

	// Displaying the new array
	cout << "The new array after assigning values is : ";
	for (int i=0; i<6 ; i++)
		cout << ar[i] << " ";          // 20 21 22 23 24 25

	return 0;

}

11、std::partition(),std::is_partitioned()

partition(beg,end,condition):-此函数用于根据参数中提到的条件对元素进行分区。
is_partitioned(beg,end,condition):-如果容器已分区,则此函数返回布尔值true,否则返回false。

#include<iostream>
#include<algorithm> // for partition algorithm
#include<vector> // for vector
using namespace std;

int main()
{
	// Initializing vector
	vector<int> vect = { 2, 1, 5, 6, 8, 7 };
	
	// Checking if vector is partitioned
	// using is_partitioned()
	is_partitioned(vect.begin(), vect.end(), [](int x)
	{
		return x%2==0;	
	}) 
	? 
	cout << "Vector is partitioned"
 	: 
 	cout << "Vector is not partitioned";
	cout << endl;
	
	// partitioning vector using partition()
	partition(vect.begin(), vect.end(), [](int x)
	{
		return x%2==0;	
	});
	
	// Checking if vector is partitioned
	// using is_partitioned()
	is_partitioned(vect.begin(), vect.end(), [](int x)
	{
		return x%2==0;	
	})
	?
	cout << "Now, vector is partitioned after partition operation"
	:
	cout << "Vector is still not partitioned after partition operation";
	cout << endl;
	
	// Displaying partitioned Vector
	cout << "The partitioned vector is : ";
	for (int &x : vect) cout << x << " ";       // 2 8 6 5 1 7
	
	return 0;
	
}

12、std::stable_partition(),std::partition_point()

stable_partition(beg,end,condition):-此函数用于根据参数中提到的条件对元素进行分区,从而保持元素的相对顺序。。
partition_point(beg,end,condition):-此函数返回一个迭代器,该迭代器指向容器的分区点,即分区范围[beg,end]中条件不为true的第一个元素。容器应该已经分区,此函数才能工作。

// C++ code to demonstrate the working of
// stable_partition() and partition_point()
#include<iostream>
#include<algorithm> // for partition algorithm
#include<vector> // for vector
using namespace std;
int main()
{
	// Initializing vector
	vector<int> vect = { 2, 1, 5, 6, 8, 7 };
	
	// partitioning vector using stable_partition()
	// in sorted order
	stable_partition(vect.begin(), vect.end(), [](int x)
	{
		return x%2 == 0;	
	});
	
	// Displaying partitioned Vector
	cout << "The partitioned vector is : ";
	for (int &x : vect) cout << x << " ";          // 2 6 8 1 5 7 
	cout << endl;
	
	// Declaring iterator
	vector<int>::iterator it1;
	
	// using partition_point() to get ending position of partition
	auto it = partition_point(vect.begin(), vect.end(), [](int x)
	{
		return x%2==0;
	});
	
	// Displaying partitioned Vector
	cout << "The vector elements returning true for condition are : ";
	for ( it1= vect.begin(); it1!=it; it1++)
		cout << *it1 << " ";        // 2 6 8
	cout << endl;
	
	return 0;
	
}

13、std::partition_copy()

partition_copy(beg,end,beg1,beg2,condition):-此函数复制参数中提到的不同容器中的分区元素。它需要5个参数。容器的开始和结束位置、必须复制元素的新容器的开始位置(条件返回为true的元素)、必须复制其他元素的新的容器的起始位置(条件为false的元素)和条件。此功能需要调整新容器的大小。

// C++ code to demonstrate the working of
// partition_copy()
#include<iostream>
#include<algorithm> // for partition algorithm
#include<vector> // for vector
using namespace std;
int main()
{
	// Initializing vector
	vector<int> vect = { 2, 1, 5, 6, 8, 7 };
	
	// Declaring vector1
	vector<int> vect1;
	
	// Declaring vector1
	vector<int> vect2;
	
	// Resizing vectors to suitable size using count_if() and resize()
	int n = count_if (vect.begin(), vect.end(), [](int x)
	{
		return x%2==0;
		
	} );
	vect1.resize(n);
	vect2.resize(vect.size()-n);
	
	// Using partition_copy() to copy partitions
	partition_copy(vect.begin(), vect.end(), vect1.begin(),
									vect2.begin(), [](int x)
	{
		return x%2==0;
	});
	
	
	// Displaying partitioned Vector
	cout << "The elements that return true for condition are : ";
	for (int &x : vect1)
			cout << x << " ";      // 2 6 8
	cout << endl;
	
	// Displaying partitioned Vector
	cout << "The elements that return false for condition are : ";
	for (int &x : vect2)
			cout << x << " ";      // 1 5 7
	cout << endl;
	
	return 0;
}


14、std::apply(),std::sum()

apply():-此函数将其参数中给定的操作一次应用于所有valarray元素,并返回一个具有操作值的新valarray。
sum():-此函数一次返回valarrays的所有元素的总和。

#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
	// Initializing valarray
	valarray<int> varr = { 10, 2, 20, 1, 30 };
	
	// Declaring new valarray
	valarray<int> varr1 ;
	
	// Using apply() to increment all elements by 5
	varr1 = varr.apply([](int x){return x=x+5;});
	
	// Displaying new elements value
	cout << "The new valarray with manipulated values is : ";
	for (int &x: varr1) cout << x << " ";  // 15 7 25 6 35
	cout << endl;
	
	// Displaying sum of both old and new valarray
	cout << "The sum of old valarray is : ";
	cout << varr.sum() << endl;           // 63
	cout << "The sum of new valarray is : ";
	cout << varr1.sum() << endl;          // 88

	return 0;
	
}

15、std::min(),std::max()

min():-此函数返回valarray的最小元素。
max():-此函数返回valarray的最大元素。

#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
	// Initializing valarray
	valarray<int> varr = { 10, 2, 20, 1, 30 };
	
	// Displaying largest element of valarray
	cout << "The largest element of valarray is : ";
	cout << varr.max() << endl;        // 30
	
	// Displaying smallest element of valarray
	cout << "The smallest element of valarray is : ";
	cout << varr.min() << endl;        // 1

	return 0;
	
}

16、std::shift(),std::cshift()

shift():-此函数在按参数中提到的数字移动元素后返回新的valarray。如果数字为正,则应用左移,如果数字为负,则应用右移。
cshift():-此函数在按参数中提到的数字循环移动(旋转)元素后返回新的valarray。如果数字为正,则应用左循环移位,如果数字为负,则应用右循环移位。

// C++ code to demonstrate the working of
// shift() and cshift()
#include<iostream>
#include<valarray> // for valarray functions
using namespace std;
int main()
{
	// Initializing valarray
	valarray<int> varr = { 10, 2, 20, 1, 30 };
	
	// Declaring new valarray
	valarray<int> varr1;
	
	// using shift() to shift elements to left
	// shifts valarray by 2 position
	varr1 = varr.shift(2);
	
	// Displaying elements of valarray after shifting
	cout << "The new valarray after shifting is : ";
	for ( int&x : varr1) cout << x << " ";         // 20 1 30 0 0
	cout << endl;
	
	// using cshift() to circularly shift elements to right
	// rotates valarray by 3 position
	varr1 = varr.cshift(-3);
	
	// Displaying elements of valarray after circular shifting
	cout << "The new valarray after circular shifting is : ";
	for ( int&x : varr1) cout << x << " ";         // 20 1 30 10 2
	cout << endl;

	return 0;
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值