【C++】C++11 STL算法(七):排列操作(Permutation operations)、数值操作(Numeric operations)

【C++】郭老二博文之:C++目录

排列操作(Permutation operations)

一、is_permutation
1、原型:
template< class ForwardIt1, class ForwardIt2 >
bool is_permutation( ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2 );

template< class ForwardIt1, class ForwardIt2, class BinaryPredicate >
bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
                 ForwardIt2 first2, BinaryPredicate p );
2、说明:

判读序列1是否是序列2的一种排列方式

3、官方demo
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
    std::vector<int> v1{1,2,3,4,5};
    std::vector<int> v2{3,5,4,1,2};
    std::cout << "3,5,4,1,2 is a permutation of 1,2,3,4,5? "
              << std::boolalpha
              << std::is_permutation(v1.begin(), v1.end(), v2.begin()) << '\n';
 
    std::vector<int> v3{3,5,4,1,1};
    std::cout << "3,5,4,1,1 is a permutation of 1,2,3,4,5? "
              << std::boolalpha
              << std::is_permutation(v1.begin(), v1.end(), v3.begin()) << '\n';
}

Output:

3,5,4,1,2 is a permutation of 1,2,3,4,5? true
3,5,4,1,1 is a permutation of 1,2,3,4,5? false
二、next_permutation
1、原型:
template< class BidirIt >
bool next_permutation( BidirIt first, BidirIt last );

template< class BidirIt, class Compare >
bool next_permutation( BidirIt first, BidirIt last, Compare comp );
2、说明:

按字典顺序生成下一个序列,如果有返回true;如果没有,生成第一个排列序列(std::sort(first, last)),并返回false。

3、官方demo
#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()));
}

Output:

aab
aba
baa
三、prev_permutation
1、原型:
template< class BidirIt >
bool prev_permutation( BidirIt first, BidirIt last);

template< class BidirIt, class Compare >
bool prev_permutation( BidirIt first, BidirIt last, Compare comp);
2、说明:

按字典顺序生成上一个序列,如果有返回true;如果没有,生成第一个排列序列(std::sort(first, last)),并返回false。

3、官方demo

打印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';
}

Output:

cba cab bca bac acb abc

数值操作(Numeric operations)

一、iota
1、原型:
template< class ForwardIt, class T >
void iota( ForwardIt first, ForwardIt last, T value );
2、说明:

以递增的值填充[first, last)范围

3、官方demo
#include <algorithm>
#include <iostream>
#include <list>
#include <numeric>
#include <random>
#include <vector>
 
int main()
{
    std::list<int> l(10);
    std::iota(l.begin(), l.end(), -4);	//以递增的值填充到链表l中
 
    std::vector<std::list<int>::iterator> v(l.size());
    std::iota(v.begin(), v.end(), l.begin());
 
    std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});	//std::shuffle不能操作std::list,因此使用vector
 
    std::cout << "Contents of the list: ";
    for(auto n: l) std::cout << n << ' ';
    std::cout << '\n';
 
    std::cout << "Contents of the list, shuffled: ";
    for(auto i: v) std::cout << *i << ' ';
    std::cout << '\n';
}

Possible output:

Contents of the list: -4 -3 -2 -1 0 1 2 3 4 5
Contents of the list, shuffled: 0 -1 3 4 -4 1 -2 -3 2 5
二、accumulate
1、原型:
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );

template< class InputIt, class T, class BinaryOperation >
T accumulate( InputIt first, InputIt last, T init, BinaryOperation op );
2、说明:

计算序列的累积值(连续加、连续乘等)

3、官方demo
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>
 
int main()
{
    std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
 
    int sum = std::accumulate(v.begin(), v.end(), 0);	// 加
 
    int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());	// 乘
 
    auto dash_fold = [](std::string a, int b) {	// 连接操作
                         return std::move(a) + '-' + std::to_string(b);
                     };
 
    std::string s = std::accumulate(std::next(v.begin()), v.end(),	// std::next是为了从第二个值开始,在前面加“-”
                                    std::to_string(v[0]), // 从第一个元素开始
                                    dash_fold);
 
    // 使用反向迭代器右折叠
    std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
                                     std::to_string(v.back()), // 从最后一个元素开始
                                     dash_fold);
 
    std::cout << "sum: " << sum << '\n'
              << "product: " << product << '\n'
              << "dash-separated string: " << s << '\n'
              << "dash-separated string (right-folded): " << rs << '\n';
}

Output:

sum: 55
product: 3628800
dash-separated string: 1-2-3-4-5-6-7-8-9-10
dash-separated string (right-folded): 10-9-8-7-6-5-4-3-2-1
三、inner_product
1、原型:
template< class InputIt1, class InputIt2, class T >
T inner_product( InputIt1 first1, InputIt1 last1,
             InputIt2 first2, T init );
			 
template<class InputIt1, class InputIt2, class T,
     class BinaryOperation1, class BinaryOperation2>
T inner_product( InputIt1 first1, InputIt1 last1,
             InputIt2 first2, T init,
             BinaryOperation1 op1,
             BinaryOperation2 op2 );
2、说明:

计算两个序列的内积:即序列1和序列2的顺序对应的元素乘积之和

3、官方demo
#include <numeric>
#include <iostream>
#include <vector>
#include <functional>
int main()
{
    std::vector<int> a{0, 1, 2, 3, 4};
    std::vector<int> b{5, 4, 2, 3, 1};
 
    int r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0);
    std::cout << "Inner product of a and b: " << r1 << '\n';
 
    int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                                std::plus<>(), std::equal_to<>());
    std::cout << "Number of pairwise matches between a and b: " <<  r2 << '\n';
}

Output:

Inner product of a and b: 21
Number of pairwise matches between a and b: 2	//成对匹配的数量
四、adjacent_difference
1、原型:
template< class InputIt, class OutputIt >
OutputIt adjacent_difference( InputIt first, InputIt last, OutputIt d_first );

template< class InputIt, class OutputIt, class BinaryOperation >
OutputIt adjacent_difference( InputIt first, InputIt last,
                          OutputIt d_first, BinaryOperation op );
2、说明:

计算相邻元素之间的差值。

3、官方demo
#include <numeric>
#include <vector>
#include <array>
#include <iostream>
#include <functional>
#include <iterator>
 
int main()
{
	std::vector v {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
    std::adjacent_difference(v.begin(), v.end(), v.begin());
 
    for (auto n : v)
        std::cout << n << ' ';
 
    std::cout << '\n';
 
    // 斐波纳契数列 
    std::array<int, 10> a {1};
    adjacent_difference(begin(a), std::prev(end(a)), std::next(begin(a)), std::plus<> {});
    copy(begin(a), end(a), std::ostream_iterator<int> {std::cout, " "});
}

Output:

2 2 2 2 2 2 2 2 2 2
1 1 2 3 5 8 13 21 34 55
五、partial_sum
1、原型:
template< class InputIt, class OutputIt >
OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first );

template< class InputIt, class OutputIt, class BinaryOperation >
OutputIt partial_sum( InputIt first, InputIt last, OutputIt d_first, BinaryOperation op );
2、说明:

以如下形式计算,并将结果保存在d_first开始的目标区域:

	*(d_first)   = *first;
	*(d_first+1) = *first + *(first+1);
	*(d_first+2) = *first + *(first+1) + *(first+2);
3、官方demo
#include <numeric>
#include <vector>
#include <iostream>
#include <iterator>
#include <functional>
 
int main()
{
    std::vector<int> v = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; // or std::vector<int>v(10, 2);
 
    std::cout << "The first 10 even numbers are: ";
    std::partial_sum(v.begin(), v.end(), 
                     std::ostream_iterator<int>(std::cout, " "));
    std::cout << '\n';
 
    std::partial_sum(v.begin(), v.end(), v.begin(), std::multiplies<int>());
    std::cout << "The first 10 powers of 2 are: ";
    for (auto n : v) {
        std::cout << n << " ";
    }
    std::cout << '\n';
}

Output:

The first 10 even numbers are: 2 4 6 8 10 12 14 16 18 20 
The first 10 powers of 2 are: 2 4 8 16 32 64 128 256 512 1024
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭老二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值