如何高速判断子集合是否相等

JohnsonElizeee 2010-11-21 11:35:55
给定一个集合{e1, e2, e3, e4, e5, ..., en},元素个n小于等于100。
从中任意取出两个子集合(集合中元素无序),要求高速判断两子集合是否相等(含有相同的元素)。
如何设计集合数据结构(元素类型不限,可以是对象,数字,或者字符等等),
如何设计判断算法(空间不限,进程数,线程数不限,唯一目标:快)。

若元素个数n小于等于1000,如何如何。
若元素个数n小于等于10000,如何如何。

谢谢!
...全文
246 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
JohnsonElizeee 2010-11-22
  • 打赏
  • 举报
回复
达人在哪?
达人在哪!
showjim 2010-11-22
  • 打赏
  • 举报
回复
子集合密集的话用位图,稀的话用hash
JohnsonElizeee 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wood87654321 的回复:]

看来真正的问题并不是等价判断,而是如何针对有限的不同对象保证hash生成的唯一性
[/Quote]
呵呵,厉害厉害,请问针对此问题有什么好的hash方法没,要保证hash的一致性(一致hash函数),要高效。谢谢。
JohnsonElizeee 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 snowwhite1 的回复:]

为集合建立一个索引,1号元素用1表示,2号元素用2表示,以此类推。当取了某一元素,相应索引号置1;若索引号完全相同,表示两集合相等。可以用位实现。也可以借用pair/set实现。复杂度O(n)。
[/Quote]
恩,用位图来做确实是个O(n)的好方法。也可以这样比,第一次在内存区M上设置位值(0或者1),针对第2个子集合,还在M上进行操作:
int count = 0; //add 1 when one element is processed in subset1
...
...
//processing subset2
assert(count);
for(int e : subset2){
if(M(e) == 1)// has been set to 1
{
count --;
continue;
}
break; //e is a different element to subset1
}

if(count == 0) return true;
return false;

算法复杂度O(n)。
谢谢。
wood87654321 2010-11-22
  • 打赏
  • 举报
回复
看来真正的问题并不是等价判断,而是如何针对有限的不同对象保证hash生成的唯一性
JohnsonElizeee 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 marcal_z 的回复:]

这个问题,我也在想知道。
[/Quote]
今天早上在车上,我有这么个思路:
不管集合元素什么类型,用哈希,先给对应上一个唯一的ID,如HashMap,这个ID是一个质数。
在取子集的时候,首先设定SSID = 1,取一个元素ex就执行SSID *= ex.ID(x = 1, 2, 3, ...)。
显然SSID做乘积操作,在size比较大的时候计算机不好处理,所以只能针对小集合。
最后这个SSID就认为是这个子集合的ID。
如果这样求出的SSID是唯一的,那么,每取完一个子集合,就能得到其SSID。
只要比较SSID就知道这两个子集合是否相等,这样,比较算法只需要一行,时间复杂度为 O(1)。

问题是质数(素数)2, 3, 5, 7, 11, 13, 17, 19, 23, ...能满足以上要求不。
即在质数中任取若干个数组成一个序列,求出它们的积M1,
不存另外一个不同的序列,使得M2 == M1。(如{2,3,5} 和 {2,3,7}是2个不同的序列)

如果质数不满足,那什么样的序列的数能满足我要的要求呢?望大家多多指教。谢谢。


flysnowhite 2010-11-22
  • 打赏
  • 举报
回复
为集合建立一个索引,1号元素用1表示,2号元素用2表示,以此类推。当取了某一元素,相应索引号置1;若索引号完全相同,表示两集合相等。可以用位实现。也可以借用pair/set实现。复杂度O(n)。
marcal_z 2010-11-22
  • 打赏
  • 举报
回复
这个问题,我也在想知道。
LeonTown 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 jonsenelizee 的回复:]

引用 11 楼 leontown 的回复:

how about "bit set"

do u mean bit-map?
further info is expected and to be appreciated!
[/Quote]

没有太仔细看需求。
假如有n个数据,就用n个bit表示每个子集。
对每个子集,设置该子集中元素所对应的bit,
最后看两个子集的“bit set”是否相等。
绿色夹克衫 2010-11-22
  • 打赏
  • 举报
回复
其实这些性质有没有都无所谓,单列到的空间足够大,比如0 - 2^128,那么碰撞的几率就很低,这样就有很大的概率是相同的。

[Quote=引用 14 楼 jonsenelizee 的回复:]
用LZ自己的思路就可以,乘法(或加法,满足交换律即可)+ 模(用位运算做也可以)算个Hash值,然后比较2个集合的Hash就可以,类似于MD5,这样也不用开额外空间作位图
用bitma……
[/Quote]
JohnsonElizeee 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 leontown 的回复:]

how about "bit set"
[/Quote]
do u mean bit-map?
further info is expected and to be appreciated!
JohnsonElizeee 2010-11-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 litaoye 的回复:]

用LZ自己的思路就可以,乘法(或加法,满足交换律即可)+ 模(用位运算做也可以)算个Hash值,然后比较2个集合的Hash就可以,类似于MD5,这样也不用开额外空间作位图
[/Quote]
谢谢谢谢,问题是这个hash函数怎么写,我的思路是用质数来做ID,求积,而且质数有没有这个性质,我实在是不敢肯定,想如果能找到一个别的数列满足我的要求也行。
用bitmap的话,可以处理比较大的集合,可以在O(n)解决问题,不失为好的办法。
但这都是比较常规的办法,我希望有人能提出比较犀利的算法,或者别的算法,打开思路。
谢谢大家参与!
pmars 2010-11-22
  • 打赏
  • 举报
回复
怎么看都不能做到N(1)吧,集合中可是有元素的!
hash还是很好用的
超级大笨狼 2010-11-22
  • 打赏
  • 举报
回复
用哈希表,复杂度取决于最小的集合O(min(N))
LeonTown 2010-11-22
  • 打赏
  • 举报
回复
how about "bit set"
绿色夹克衫 2010-11-22
  • 打赏
  • 举报
回复
用LZ自己的思路就可以,乘法(或加法,满足交换律即可)+ 模(用位运算做也可以)算个Hash值,然后比较2个集合的Hash就可以,类似于MD5,这样也不用开额外空间作位图
打字员 2010-11-22
  • 打赏
  • 举报
回复
x1*x2*x3/(x1+x2+x3)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧