【C++】C++11 STL算法(五):设置操作(Set operations)、堆操作(Heap operations)

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

设置操作(Set operations)

一、includes
1、原型:
template< class InputIt1, class InputIt2 >
bool includes( InputIt1 first1, InputIt1 last1,
           InputIt2 first2, InputIt2 last2 );
		   
template< class InputIt1, class InputIt2, class Compare >
bool includes( InputIt1 first1, InputIt1 last1,
           InputIt2 first2, InputIt2 last2, Compare comp );
2、说明:

如果一个集合是另一个集合的子集,则返回true

3、官方demo
#include <iostream>
#include <algorithm>
#include <cctype>
#include <vector>
 
int main()
{
  std::vector<char> v1 {'a', 'b', 'c', 'f', 'h', 'x'};
  std::vector<char> v2 {'a', 'b', 'c'};
  std::vector<char> v3 {'a', 'c'};
  std::vector<char> v4 {'g'};
  std::vector<char> v5 {'a', 'c', 'g'};
 
  for (auto i : v1) std::cout << i << ' ';
  std::cout << "\nincludes:\n" << std::boolalpha;
 
  for (auto i : v2) std::cout << i << ' ';
  std::cout << ": " << std::includes(v1.begin(), v1.end(), v2.begin(), v2.end()) << '\n';
  for (auto i : v3) std::cout << i << ' ';
  std::cout << ": " << std::includes(v1.begin(), v1.end(), v3.begin(), v3.end()) << '\n';
  for (auto i : v4) std::cout << i << ' ';
  std::cout << ": " << std::includes(v1.begin(), v1.end(), v4.begin(), v4.end()) << '\n';
  for (auto i : v5) std::cout << i << ' ';
  std::cout << ": " << std::includes(v1.begin(), v1.end(), v5.begin(), v5.end()) << '\n';
 
  auto cmp_nocase = [](char a, char b) {
    return std::tolower(a) < std::tolower(b);
  };
 
  std::vector<char> v6 {'A', 'B', 'C'};
  for (auto i : v6) std::cout << i << ' ';
  std::cout << ": (case-insensitive) "
            << std::includes(v1.begin(), v1.end(), v6.begin(), v6.end(), cmp_nocase)
            << '\n';
}

Output:

a b c f h x
includes:
a b c : true
a c : true
g : false
a c g : false
A B C : (case-insensitive) true
二、set_difference
1、原型:
template< class InputIt1, class InputIt2, class OutputIt >
OutputIt set_difference( InputIt1 first1, InputIt1 last1,
                     InputIt2 first2, InputIt2 last2,
                     OutputIt d_first );
					 
template< class InputIt1, class InputIt2, class OutputIt, class Compare >
OutputIt set_difference( InputIt1 first1, InputIt1 last1,
                     InputIt2 first2, InputIt2 last2,
                     OutputIt d_first, Compare comp );
2、说明:

计算两个集合的差:将[first1,last1)中剔除[first1,last2)的元素,输出到d_first中

3、官方demo
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
 
int main() {
    std::vector<int> v1 {1, 2, 5, 5, 5, 9};
    std::vector<int> v2 {2, 5, 7};
    std::vector<int> diff;
 
    std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), 
                        std::inserter(diff, diff.begin()));
 
    for (auto i : v1) std::cout << i << ' ';
    std::cout << "minus ";
    for (auto i : v2) std::cout << i << ' ';
    std::cout << "is: ";
    for (auto i : diff) std::cout << i << ' ';
    std::cout << '\n';
}

Output:

1 2 5 5 5 9 minus 2 5 7 is: 1 5 5 9
三、set_intersection
1、原型:
template< class InputIt1, class InputIt2, class OutputIt >
OutputIt set_intersection( InputIt1 first1, InputIt1 last1,
                       InputIt2 first2, InputIt2 last2,
                       OutputIt d_first );
					   
template< class InputIt1, class InputIt2, class OutputIt, class Compare >
OutputIt set_intersection( InputIt1 first1, InputIt1 last1,
                       InputIt2 first2, InputIt2 last2,
                       OutputIt d_first, Compare comp );
2、说明:

计算两个集合从交集

3、官方demo
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
    std::vector<int> v1{1,2,3,4,5,6,7,8};
    std::vector<int> v2{5,7,9,10};
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());
 
    std::vector<int> v_intersection;
 
    std::set_intersection(v1.begin(), v1.end(),
                          v2.begin(), v2.end(),
                          std::back_inserter(v_intersection));
    for(int n : v_intersection)
        std::cout << n << ' ';
}

Output:

5 7
四、set_symmetric_difference
1、原型:
template< class InputIt1, class InputIt2, class OutputIt >
OutputIt set_symmetric_difference( InputIt1 first1, InputIt1 last1,
                               InputIt2 first2, InputIt2 last2,
                               OutputIt d_first );
							   
template< class InputIt1, class InputIt2, class OutputIt, class Compare >
OutputIt set_symmetric_difference( InputIt1 first1, InputIt1 last1,
                               InputIt2 first2, InputIt2 last2,
                               OutputIt d_first, Compare comp );
2、说明:

计算两个集合之间的对称差:两个集合的并集减去它们的交集

3、官方demo
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main()
{
    std::vector<int> v1{1,2,3,4,5,6,7,8     };
    std::vector<int> v2{        5,  7,  9,10};
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());
 
    std::vector<int> v_symDifference;
 
    std::set_symmetric_difference(
        v1.begin(), v1.end(),
        v2.begin(), v2.end(),
        std::back_inserter(v_symDifference));
 
    for(int n : v_symDifference)
        std::cout << n << ' ';
}

Output:

1 2 3 4 6 8 9 10
五、set_union
1、原型:
template< class InputIt1, class InputIt2, class OutputIt >
OutputIt set_union( InputIt1 first1, InputIt1 last1,
                InputIt2 first2, InputIt2 last2,
                OutputIt d_first );
				
template< class InputIt1, class InputIt2, class OutputIt, class Compare >
OutputIt set_union( InputIt1 first1, InputIt1 last1,
                InputIt2 first2, InputIt2 last2,
                OutputIt d_first, Compare comp );
2、说明:

计算两个集合的并集

3、官方demo
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
 
int main()
{
    {
        std::vector<int> v1 = {1, 2, 3, 4, 5}; 
        std::vector<int> v2 = {      3, 4, 5, 6, 7}; 
        std::vector<int> dest1;
 
        std::set_union(v1.begin(), v1.end(),
                       v2.begin(), v2.end(),                  
                       std::back_inserter(dest1));
 
        for (const auto &i : dest1) {
            std::cout << i << ' ';
        }   
        std::cout << '\n';
    }
    {
        std::vector<int> v1 = {1, 2, 3, 4, 5, 5, 5}; 
        std::vector<int> v2 = {      3, 4, 5, 6, 7}; 
        std::vector<int> dest1;
 
        std::set_union(v1.begin(), v1.end(),
                       v2.begin(), v2.end(),                  
                       std::back_inserter(dest1));
 
        for (const auto &i : dest1) {
            std::cout << i << ' ';
        }   
        std::cout << '\n';
    }
}

Output:

1 2 3 4 5 6 7 
1 2 3 4 5 5 5 6 7

堆操作(Heap operations)

一、is_heap
1、原型:
template< class RandomIt >
bool is_heap( RandomIt first, RandomIt last );

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

判断是否为最大堆:父结点的键值总是大于或等于任何一个子结点的键值时为最大堆

3、官方demo
#include <iostream>
#include <algorithm>
#include <vector>
 
int main()
{
    std::vector<int> v { 3, 1, 4, 1, 5, 9 };
 
    std::cout << "initially, v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    if (!std::is_heap(v.begin(), v.end())) {
        std::cout << "making heap...\n";
        std::make_heap(v.begin(), v.end());
    }
 
    std::cout << "after make_heap, v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
}

Output:

initially, v: 3 1 4 1 5 9 
making heap...
after make_heap, v: 9 5 4 1 1 3
二、is_heap_until
1、原型:
template< class RandomIt >
RandomIt is_heap_until( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
RandomIt is_heap_until( RandomIt first, RandomIt last, Compare comp );
2、说明:

找到从first开始最大范围的最大堆

3、官方demo
#include <iostream>
#include <algorithm>
#include <vector>
 
int main()
{
    std::vector<int> v { 3, 1, 4, 1, 5, 9 };
 
    std::make_heap(v.begin(), v.end());
 
    // 可能把堆搞乱了
    v.push_back(2);
    v.push_back(6);
 
    auto heap_end = std::is_heap_until(v.begin(), v.end());
 
    std::cout << "all of v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    std::cout << "only heap: ";
    for (auto i = v.begin(); i != heap_end; ++i) std::cout << *i << ' ';
    std::cout << '\n';
}

Output:

all of v:  9 5 4 1 1 3 2 6 
only heap: 9 5 4 1 1 3 2
三、make_heap
1、原型:
template< class RandomIt >
void make_heap( RandomIt first, RandomIt last );
2、说明:

生成堆

3、官方demo
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
 
int main()
{
    std::cout << "Max heap:\n";
 
    std::vector<int> v { 3, 2, 4, 1, 5, 9 };	// 最初序列
 
    std::cout << "initially, v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    std::make_heap(v.begin(), v.end());	// 产生最大堆
 
    std::cout << "after make_heap, v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    std::pop_heap(v.begin(), v.end());	// 将最大元素移至尾部(待删除)
 
    std::cout << "after pop_heap, v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    auto top = v.back();
    v.pop_back();	// 删除尾部元素
    std::cout << "former top element: " << top << '\n';
 
    std::cout << "after removing the former top element, v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n' << '\n';
 
    std::cout << "Min heap:\n";
 
    std::vector<int> v1 { 3, 2, 4, 1, 5, 9 };
 
    std::cout << "initially, v1: ";
    for (auto i : v1) std::cout << i << ' ';
    std::cout << '\n';
 
    std::make_heap(v1.begin(), v1.end(), std::greater<>{});	// 产生最小堆
 
    std::cout << "after make_heap, v1: ";
    for (auto i : v1) std::cout << i << ' ';
    std::cout << '\n';
 
    std::pop_heap(v1.begin(), v1.end(), std::greater<>{});	// 将最小元素移至尾部(待删除)
 
    std::cout << "after pop_heap, v1: ";
    for (auto i : v1) std::cout << i << ' ';
    std::cout << '\n';
 
    auto top1 = v1.back();
    v1.pop_back();	// 删除尾部数据
    std::cout << "former top element: " << top1 << '\n';
 
    std::cout << "after removing the former top element, v1: ";
    for (auto i : v1) std::cout << i << ' ';
    std::cout << '\n';
}

Output:

Max heap:
initially, v: 3 2 4 1 5 9 
after make_heap, v: 9 5 4 1 2 3 
after pop_heap, v: 5 3 4 1 2 9 
former top element: 9
after removing the former top element, v: 5 3 4 1 2 

Min heap:
initially, v1: 3 2 4 1 5 9 
after make_heap, v1: 1 2 4 3 5 9 
after pop_heap, v1: 2 3 4 9 5 1 
former top element: 1
after removing the former top element, v1: 2 3 4 9 5
四、push_heap
1、原型:
template< class RandomIt >
void push_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void push_heap( RandomIt first, RandomIt last, Compare comp );
2、说明:

将位于last-1的元素插入到[first, last-1)中,并保持最大堆。在此之前需要执行push_back将新元素添加到尾部。

3、官方demo
#include <iostream>
#include <algorithm>
#include <vector>
 
int main()
{
    std::vector<int> v { 3, 1, 4, 1, 5, 9 };
 
    std::make_heap(v.begin(), v.end());
 
    std::cout << "v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    v.push_back(6);
 
    std::cout << "before push_heap: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    std::push_heap(v.begin(), v.end());
 
    std::cout << "after push_heap: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
}

Output:

v: 9 5 4 1 1 3 
before push_heap: 9 5 4 1 1 3 6 
after push_heap:  9 5 6 1 1 3 4
五、pop_heap
1、原型:
template< class RandomIt >
void pop_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void pop_heap( RandomIt first, RandomIt last, Compare comp );
2、说明:

交换位于first和last-1的值,然后使子范围[first, last-1)成为堆。
等于把最大堆中第一个元素即最大的值“删除”,这里的删除是加引号,因为没有真正删除。紧接着使用pop_back才能真正删除最大的元素。

3、官方demo
#include <iostream>
#include <algorithm>
#include <vector>
 
int main()
{
    std::vector<int> v { 3, 1, 4, 1, 5, 9 };
 
    std::make_heap(v.begin(), v.end());
 
    std::cout << "v: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    std::pop_heap(v.begin(), v.end()); // 把最大的元素移到最后,此时还没有删除
 
    std::cout << "after pop_heap: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
 
    int largest = v.back();
    v.pop_back();  // 在这里会真正删除最大元素。
    std::cout << "largest element: " << largest << '\n';
 
    std::cout << "heap without largest: ";
    for (auto i : v) std::cout << i << ' ';
    std::cout << '\n';
}

Output:

v: 9 5 4 1 1 3 
after pop_heap: 5 3 4 1 1 9 
largest element: 9
heap without largest: 5 3 4 1 1
六、sort_heap
1、原型:
template< class RandomIt >
void sort_heap( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void sort_heap( RandomIt first, RandomIt last, Compare comp );
2、说明:

将最大堆转换成升序排列

3、官方demo
#include <algorithm>
#include <vector>
#include <iostream>
 
int main()
{
    std::vector<int> v = {3, 1, 4, 1, 5, 9}; 
 
    std::make_heap(v.begin(), v.end());
 
    std::cout << "heap:\t";
    for (const auto &i : v) {
        std::cout << i << ' ';
    }   
 
    std::sort_heap(v.begin(), v.end());
 
    std::cout << "\nsorted:\t";
    for (const auto &i : v) {                                                   
        std::cout << i << ' ';
    }   
    std::cout << '\n';
}

Output:

heap:   9 4 5 1 1 3 
sorted: 1 1 3 4 5 9
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

郭老二

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

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

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

打赏作者

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

抵扣说明:

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

余额充值