说我有一个数组arr[] = {1 , 3 , 5, 12124, 24354, 12324, 5}
我想知道5
中值O(1)
(即2)的索引。
我应该怎么做呢?
P.S: 1.在我的整个计划中,我将只找到指数而不是反之亦然(通过指数获得价值) 2.数组可以有重复数据。
答案 0 :(得分:2)
使用C ++ 11中的std::unordered_map
将元素映射为键,将索引映射为值。然后,您可以在 amortized O(1)
复杂性中获得对查询的回答。 std::unordered_map
将起作用,因为没有像你所说的重复,但会花费额外空间的线性大小。
如果您的值的范围不是太大,您也可以使用数组。这将产生更好的theta(1)
复杂性。
答案 1 :(得分:2)
如果你可以保证数组中没有重复项,你最好的选择是创建一个unordered_map
,其中map键是数组值,map值是它的索引。
我写了一个方法,将数组转换为unordered_map
。
#include <unordered_map>
#include <iostream>
template <typename T>
void arrayToMap(const T arr[], size_t arrSize, std::unordered_map<T, int>& map)
{
for(int i = 0; i < arrSize; ++i) {
map[arr[i]] = i;
}
}
int main()
{
int arr[] = { 1 , 3 , 5, 12124, 24354, 12324, 5 };
std::unordered_map<int, int> map;
arrayToMap(arr, sizeof(arr)/sizeof(*arr), map);
std::cout << "Value" << '\t' << "Index" << std::endl;
for(auto it = map.begin(), e = map.end(); it != e; ++it) {
std::cout << it->first << "\t" << it->second << std::endl;
}
}
但是,在您的示例中,您使用值5
两次。这会在上面的代码中导致奇怪的输出。输出的地图没有索引2
的值。即使你使用数组,你也会遇到类似的问题(即你应该使用2或6的值?)。
如果您确实需要这两个值,则可以使用unordered_multimap
,但使用operator[]
访问元素的语法并不容易(您必须使用{ {1}}返回一个迭代器。)
unordered_multipmap::find()
最后,您应该考虑template <typename T>
void arrayToMap(const T arr[], size_t arrSize, std::unordered_multimap<T, int>& map)
{
for(int i = 0; i < arrSize; ++i) {
map.emplace(arr[i], i);
}
}
的快速查找时间O(1)带来一些开销,因此它比简单数组使用更多内存。但是如果你最终使用一个数组(相对更高的内存效率),搜索特定值肯定是O(n),其中n是值的索引。
编辑 - 如果您需要保留最低索引的副本而不是最高索引,则可以反转插入顺序:
unordered_map
答案 2 :(得分:1)
使用unordered_multimap(仅限C ++ 11),其值为键,位置索引为值。