假设您遇到以下问题。您有两个具有一对一映射的索引集。为简单起见,假设您有一个类似int a [] = {21, 30, 45, 78}
的数组,此列表将{1,2,3,4}映射到{21,30,45,78}。获取反向映射的最有效方法是什么,即给定索引30
,您希望算法为2
返回45
,您需要3
和等等。我能想到以下几点:
索引的二进制搜索。这具有内存效率,并且具有复杂性O(log n)
。
拥有一个包含79
元素且reverseMap[21] = 1, reverseMap[30] = 2, reverseMap[45] = 3, reverseMap[78] = 4
的数组。这是O(1)
,因此速度更快,但内存效率不高。
对于我的应用程序,内存和速度都很重要。我缺乏记忆,因为这是一个数字运算代码,因此可以使用数亿个点。速度也很重要,因为算法将被多次调用。
我觉得哈希表在这里很有用,但我对它的评论知之甚少。我对这个问题有任何见解表示感谢。此外,由于编码是在c++
中完成的,我希望看到使用STL
而不是外部库的方法。
答案 0 :(得分:2)
一如既往:个人资料。我们可以猜测,但如果不运行代码,我们可能会错。我做了一个rough benchmark on ideone(时间基于我的电脑)。我在一个拥有一千万个元素的数组中做了十万个unsigned int
的查找(我厌倦了等待你的“数亿”),这些都是我的结果:
unsorted vector found 1633382974 in 2140 ticks.
sorted vector found 1633382974 in 62 ticks.
unordered_map found 1633382974 in 16 ticks.
std::map found 1633382974 in 172 ticks. //that's half the time of a blink
但是我必须注意,在程序的内存中维护这些将比未排序的向量有一些开销。如果我们将创建时间添加到十万次查找的时间,我们得到:
unsorted vector found 1633382974 in 2141 ticks.
sorted vector found 1633382974 in 1797 ticks.
unordered_map found 1633382974 in 16218 ticks.
std::map found 1633382974 in 30749 ticks. //a full thirty seconds
因此,正如您所看到的,时间完全取决于您在代码中执行的操作。尝试不同的事情,通过优化时间,并以最快的速度为您的代码服务。
答案 1 :(得分:0)
获得反向映射的最有效方法是什么
双std::map<value, value>
。或std::unordered_map
I.e.任何地图类,双重。
即第一个映射将值从arrayA映射到arrayB,第二个映射将值从arrayB映射到arrayA。或者首先将map映射到value,然后将value映射到index。
您可以使用std::lower_bound
(二分搜索)和两个std::vector<std::pair<value, value> >
执行相同操作,但您需要确保对所有数据进行排序。它会比两个std::map
使用更少的内存,但是你很可能会花更多的时间来确保数据的排序。
对于我的应用程序,内存和速度都很重要
数亿点
切换到64位,购买额外的内存。或者将已排序的数据存储在磁盘上(允许对部分加载的数据进行二进制搜索)并忘记速度,或尝试使用“从stdin读取,立即写入stdout”方式以某种方式处理它。请注意,硬件比开发时间便宜。如果不知道您的数据类型,就无法推荐其他任何内容。