C++集合操作之集合差集:std::set_difference

 

C++集合操作之集合并集:std::set_difference

 

算法set_difference可以用来求两个集合的差集,此处的集合可以为std::set,也可以是std::multiset,但是不可以是hash_set以及hash_multiset。为什么呢?因为set_difference要求两个区间必须是有序的(从小到大排列),std::set和std::multiset为有序序列,而hash_set以及hash_multiset为无序序列。

算法set_difference可构造区间S1,S2的差集(出现于S1但不出现于S2的元素),即S1-S2;返回值为指向输出区间的尾端。
由于区间S1,S2内的每个元素都不需唯一,因此,如果某个值在S1中出现m次,在S2中出现n次,那么该值在输出区间中出现的次数为max(m-n,0),且全部来自S1。
  set_difference为稳定操作,即输出区间内的每个元素的相对顺序都和S1内的相对顺序相同。

一定谨记:两个区间必须是有序区间(从小到大)

源代码如下:

 

template<class InputIterator1,class InputIterator2,class OutputIterator>
OutputIterator set_difference(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2,OutputIterator result)
{
	while (first1!=last1 && first2!=last2) //若均未到达尾端,则进行以下操作
	{
		//在两个区间内分别移动迭代器。当第一区间的元素等于第二区间的元素时(此值同时存在于两个区间中)
		//同时移动first1,first2;当第一区间元素大于第二区间元素时,只让第二区间前进;
		//前两种情况的处理保证了当第一区间元素小于第二区间元素时,第一区间的元素只存在于第一区间,而不存在于第二区间;于是将该值记录,并且移动result		
		if (*first1<*first2)  
		{
			*result=*first1;   //既然走到这一步,说明first2前的元素没有与first1所指元素相同的元素(有序区间的特性)
			first1++;
			result++;
		}
		else if (*first2<*first1)			
			first2++;		
		else
		{		
			first1++;
			first2++;		
		}		
	}	
	return copy(first1,last1,result); 	
}


示例:

int main(void)
{
	int iarr1[]={1,2,3,3,4,5,6,7};
	int iarr2[]={1,4,3,9,10};
	multiset<int> iset1(begin(iarr1),end(iarr1));
	multiset<int> iset2(begin(iarr2),end(iarr2));
	vector<int> ivec(10);  
	auto iter=set_difference(iset1.begin(),iset1.end(),iset2.begin(),iset2.end(),ivec.begin());	//ivec为:2,3,5,6,7
	ivec.resize(iter-ivec.begin());//重新确定ivec大小
	return 0;
}

其实 ,上述代码并不仅限于对两个集合求差集,只要是两个有序区间,均可以用此代码求差集。

用于非set场合:

 

int main(void)
{
	int iarr1[]={1,2,3,3,6,7,4,5};
	int iarr2[]={1,4,3,10,9};
	std::sort(begin(iarr1),end(iarr1));
	std::sort(begin(iarr2),end(iarr2));
	vector<int> ivec(10);  
	auto iter=set_difference(begin(iarr1),end(iarr1),begin(iarr2),end(iarr2),ivec.begin());	//ivec为:2,3,5,6,7
	ivec.resize(iter-ivec.begin());//重新确定ivec大小
	return 0;
}
扫描二维码,关注“小眼睛的梦呓”公众号,在手机端查看文章
扫描二维码,关注“清远的梦呓”公众号,在手机端查看文章

 

 

 

  • 9
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`std::set_difference`是C++标准库中的一个算法函数,用于计算两个有序集合差集。它将第一个集合中存在而第二个集合中不存在的元素复制到一个新的集合中。 以下是两个使用`std::set_difference`函数的C++示例: 示例1: ```cpp #include <iostream> #include <algorithm> #include <vector> int main() { int iarr1[] = {1, 2, 3, 3, 6, 7, 4, 5}; int iarr2[] = {1, 4, 3, 10, 9}; std::sort(std::begin(iarr1), std::end(iarr1)); std::sort(std::begin(iarr2), std::end(iarr2)); std::vector<int> ivec(10); auto iter = std::set_difference(std::begin(iarr1), std::end(iarr1), std::begin(iarr2), std::end(iarr2), std::begin(ivec)); ivec.resize(iter - std::begin(ivec)); for (int num : ivec) { std::cout << num << " "; } return 0; } ``` 示例2: ```cpp #include <iostream> #include <algorithm> #include <set> #include <vector> int main() { int iarr1[] = {1, 2, 3, 3, 4, 5, 6, 7}; int iarr2[] = {1, 4, 3, 9, 10}; std::multiset<int> iset1(std::begin(iarr1), std::end(iarr1)); std::multiset<int> iset2(std::begin(iarr2), std::end(iarr2)); std::vector<int> ivec(10); auto iter = std::set_difference(iset1.begin(), iset1.end(), iset2.begin(), iset2.end(), ivec.begin()); ivec.resize(iter - ivec.begin()); for (int num : ivec) { std::cout << num << " "; } return 0; } ``` 这两个示例分别使用了数组和`multiset`作为输入集合,并使用`std::set_difference`函数计算差集。最后,将差集输出到一个新的`vector`中,并打印出来。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值