求两个集合的差集
题目描述:
现有A、B两组数据如下:
A = {12、23、18、15、12、……};
B = {14、12、26、14、15、……};
现在要进行两个集合(准确的说集合应该是没有重复元素的,这里为叙述方便不做区分)的差集(A - B)处理——去掉A中与B中相同的元素,并且处理后的数据不应有重复数据。
注意:
(1)每个待处理的集合可能有很多重复元素,建议先除去每个集合中的重复元素再做差集处理;
(2)A、B中重复数据的个数是不固定的;
解题过程:
1、建立集合的存储结构
2、去除集合中的重复元素
3、将无重复元素的两个集合作差集运算
下面分别讨论
建立集合的存储结构
数组:因为集合中元素的个数是不确定的,且元素应方便查找、删除,并且应方便访问,这样在数组不是很大的情况下动态数组成了首选。
链表:本程序也可以用链式结构来实现。(本文中先不进行讨论)
去除集合中的重复元素
思路:
如果我们要实现从集合A中去除重复元素,我们可以设置一个辅助集合B,依次从A中取出元素将其放入集合B中,只是在放入B之前需要检查B中是否已经存在该元素了。这样将A中所有元素按此操作一边后,B就是A去除重复后的集合。
实现:
按照上面思路看起来需要B集合这个辅助空间,但是其实实现时我们可以利用A本身实现B的功能。A集合需要从头开始对所有元素操作一遍,但是每个元素在用过一次之后便没用了,这样A集合便被分成两部分——访问过的和没有访问过的。如果顺序访问的话,就是前一部分是已经访问过的,后一部分是没有访问过的。这样我们可以将无重复元素存放在前面访问过的空间里。
这个思路实现起来很简单,开始时,A中的第一个元素肯定是包含在无重复集合中的,从A中第二个元素开始依次向后取元素,判断该元素是否在前面已经出现,如果没有则将其放到前面已有元素的后面,如果出现过则不用管它,继续下面的操作。这样进行下来,数组的五重复元素全部集中到集合的前一部分,后面的数完全可以不用管他们。在操作完之后,为了节省空间可以重新申请合适大小的空间存放,而把多余的空间释放掉。该思路可以简单的概括为:无重复元素前移。
下面是该算法的伪C代码实现:
设集合用数组A表示,其可以进行的操作有:
isexist( A,p,r ,e) 表示数组A的从第p个到第r个元素中(包括r) 是否存在元素e。
int trim(A,len)
{
cnt = 0;//当前无重复元素的个数
for( i form 1 to len - 1 )
{
if( ! isexist( A,0,cnt,A[i]) )
{
cnt += 1;
if( cnt != i)
{
A[cnt] = A[i];
}
}
}
return cnt;
}
将无重复元素的两个集合作差集运算
作两个集合差集的思路比上面还简单。如要完成 A = A – B 运算,只需对A中所有元素判断其是否在B中已经存在,若存在则不管它,继续判断下一个。若不存在则将其放入A集合的前面部分。(与上面去除重复元素类似,学过C语言的都能看出来,这里就不多说了。)
发表于 @ 2007年05月20日 12:48:00|评论(loading...)|收藏