有没有一种最快的方法来计算数组中的对象重复而不是HashTable?

时间:2011-02-10 11:37:43

标签: c++ optimization hashtable repeat

我会努力尽可能清楚。我已经实现了我的解决方案并且它有效,我只需要知道是否最好使用其他数据结构而不是哈希表

这是一个大学问题,但我已经提交给老师并且它有效,我只是想知道是否有人会以不同方式做到这一点。

所以,这就是问题所在:

给定图像(PPM 3,所有数据以RGB格式存储在ASCII中) 例如

P3
# The P3 means colors are in ASCII, then 3 columns and 2 rows,
# then 255 for max color, then RGB triplets
3 2
255
255   0   0     0 255   0     0   0 255
255 255   0   255 255 255     0   0   0

我需要将每个像素除以给定的常数,这将是2的幂(2,4,8 ............ 64,128)

c= 32;
Pixel2(255/c,255/c,255/c) = Pixel2(7,7,7)

然后,我需要将所有像素转换为给定宽度的补丁,补丁将累积其包含的像素的RGB值

e.g。

w=3;   imageW = 10; imageH=10;
Patch[0].r = Pixel[0].r + Pixel[1].r + Pixel[2].r +
             Pixel[10].r + Pixel[11].r + Pixel[12].r +
             Pixel[20].r + Pixel[21].r + Pixel[22].r;
Patch[0].g = Same for g component;
Patch[0].b = Same for b component;

Patch[1].r = Pixel[1].r + Pixel[2].r + Pixel[3].r +
             Pixel[11].r + Pixel[12].r + Pixel[13].r +
             Pixel[21].r + Pixel[22].r + Pixel[23].r;
etc…

然后,我需要计算图像中每个补丁的重复次数。 所以,我所做的就是我有Image类,它从文件(ifstream)读取图像,还有Pixel类,它有r,g,b和nAparations组件。我读取了像素,将它们除以给定的常数,并获得补丁,其中包含了包含像素的值。

之后我们在Image类中有一个数据向量,它是一个Patches对象数组 e.g。

data = [Patch0{r comp,g comp, b comp, 1 parition}, Patch1{r comp,g comp, b comp, 1 parition} …..];

现在,我已经完成了它使用哈希表,插入每个修补程序,如果它已经插入,只需更新它的nAppearances组件,如果没有,插入它。 插入完所有内容后,返回一个包含哈希表中所有元素的向量。 这个向量只有每个Patch的一个发生点,并且它的nAppearances组件将汇总每个Patch出现在图像中的次数。

还有其他方法吗?或者哈希表是最好的方法吗?

另外,你会使用什么样的哈希函数?目前我正在使用

hash = patch.r * 1 + patch.g *2 + patch.b*3;
tableSize = maximun number of patches (assuming no one repeats)
insert into table[hash%tableSize];

哈希表允许冲突,表中的每个位置都有一个元素列表。

对不起,如果它很大,只是想清楚。如果我的英语不够好,也很抱歉! 感谢。

2 个答案:

答案 0 :(得分:0)

2件事

首先:如果你想要散列颜色:

如果R,G和B是从00到FF的颜色,最简单的事情就是创建一个24位的散列函数,即RRGGBB然后用一个与散列表大小相对应的素数来修改它。你的哈希表大小是多少?它是素数吗?

例如65536将是一个非常糟糕的哈希表大小选择。 65539没问题。

unsigned int colornum(unsigned int red,unsigned int green,unsigned int blue) {    返回(红色<< 16 |绿色<< 8 |蓝色); }

然后哈希只是colornum(r,g,b) % hashTableSize;

哈希的替代方案: 使用带有RGB 24位数字的std :: set,或使用rgb数字,但使用24位数字进行比较。这样你就可以计算重复数量。它没有哈希那么快。

顺便说一句,如果你负担得起,2 ^ 24只有16M,如果你使用了一个可以使用2MB的bitset。您可以浏览所有颜色,为每种颜色设置“标记”,然后以这种方式重复计算。

答案 1 :(得分:0)

使用@CashCow哈希函数我已经获得了相当快的速度。

unsigned int colornum(unsigned int red,unsigned int green,unsigned int blue){return(red<< 16 | green<< 8 | blue); }

然后hash就是colornum(r,g,b)%hashTableSize;

问题是,我需要计算大量图像的补丁重复次数(一次一个),并且它们可以变化很大(一个可能只有81个补丁,10x10图像,其他可能是1024x1024,最多+ 1百万个补丁,如果所有都是不同的..)

所以我在为每个图像调整hashTableSize(colornum(r,g,b)%hashTableSize)时遇到了问题,因为非常小的图像的大数字不是最佳的,相反的是造成很多碰撞...... 我还研究了其他着名的快速哈希函数,如murmurhash2,但我不知道如何正确实现它们。 (我是否仍然需要对返回的unsigned int执行%hashtableSize?因为如果它是肯定的那么我认为它们不应该比@CashCow更快,因为我做了很少的操作)

如果有任何迹象,就在此之后,我将需要检索补丁数组并对其进行排序(因为我需要比较它们并找出差异,据我所知,最快的方式比较两个对象数组它首先让它们排序正确?)所以如果你知道任何方法可以快速计算重复次数,并且让我以后检索它已经排序了说它。

我在想一个平衡的树可能会做到这一点,它的渐变最差的是查找和插入,但是我已经摆脱了截然不同大小的图像的问题,而且我也能够检索它们排序通过trasversal Inorder(不知道它是英文的名字..)。 任何有关这方面的想法都会被欣赏。再次感谢!