如何在多个集合上找出相同的ID号的算法 ( 积分: 100 )

  • 主题发起人 主题发起人 A delphi
  • 开始时间 开始时间
A

A delphi

Unregistered / Unconfirmed
GUEST, unregistred user!
这里有一个算法:
如何在多个集合上找出相同的ID号。
比喻:
Set1 = (0..N);
最大可能 =MaxInt 其中数字没有重复 如 2, 3, 66, 777, 12, 434343, 333, 32, 344, 554, 332223, 3332, 41, 13
Set2 = (0..N);
最大可能 =MaxInt 其中数字没有重复 如 12, 13, 626, 7377, 4434343, 3332, 327, 8344, 9554, 2, 39332
Set3 = (0..N);
最大可能 =MaxInt 其中数字没有重复 如 12, 2, 16326, 172377, 24434343, 3332, 13 2327, 8344, 19554, 122, 139332
////////////////////// 如何以最快的速度得出结果 计算出: 2 12, 3332
现在加了 12
手误
 
不太明白你的意思,第一组数中没有12,不知道你是根据什么算的。
应该没有什么好办法,只能一个一个循环了。
 
是Integer数据, 这些集合保存在文件中,读取到数组中,也就是多组集合
 
如果你的数字没有maxint那么大,就好办多了。
不过,你的物理加虚拟内在足够大得BT的话,也可以试一试:
1)创建一个数组:a: array [0..maxint-1] of Byte;
2)把数组a的内容全清为0。
3)把你的每个集合中的item作为数组a的下标,直接在数组a中登记它出现的次数:
for i := 0 to length(set0) - 1do
Inc(a[set0]);
for i := 0 to length(set1) - 1do
Inc(a[set1]);
.....
4)在a中,就是你的各个ID出现的次数了。
 
可以借鉴堆排序的方法,把每个数组先升序排序,然后从尾部开始比较起,看各个数组的最后一个元素,谁大就删除谁,如果相等,就另行记录。这样应该还是比较快的。
 
1.设A为元素最少的集合(如果无法通过简单办法知道谁最短,就用第一个集合)
2.对A进行排序,形成有序数组A',同时声明一个与A'长度相等的布尔数组B
3.依次遍历A之外的其它集合[X]
3.1.将B的元素全部置为假
3.2.遍历集合X中的元素,使用二分法在A'中进行定位,如果定位成功,则将B中的对应元素置为真
3.3.遍历X完毕,将A'中在B数组中为假的元素删除,形成更加精简的相同子集
4.遍历其它集合完毕,数组A'即为所求
算法复杂度的计算:
设有M个集合,每个集合元素的平均个数为N个,最后得到的相同元素数量为X个
总体复杂度 =
O( N * Log2(N) ) //为A排序,生成A'
+ O( (M-1) * ( ( N * Log2(N) + X * Log2(X) )/2 + N ) //有序匹配+有序数组缩小
在最糟糕的情况下,总复杂度为 O( M * N * Log2(N) )
虽然在复杂度的数量级上没有什么提高,但是,本算法只进行了一次排序,之后都是在进
行匹配,并且,随着循环的进行,由于A'在不断的缩小,能有效的消除多余的排序或者匹配
动作,与对每个集合都先排序再匹配的算法相比较,在时间效率方面有很大优势。而与时间
复杂度为O(M*N)的简单数组遍历算法相比较,在空间效率上优势非常明显,是两者的折衷。
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
772
import
I
后退
顶部