哪个STL用于在C ++中的O(1)中按值查找索引

时间:2015-08-20 04:08:15

标签: c++ algorithm stl

说我有一个数组arr[] = {1 , 3 , 5, 12124, 24354, 12324, 5}

我想知道5中值O(1)(即2)的索引。
我应该怎么做呢?

P.S: 1.在我的整个计划中,我将只找到指数而不是反之亦然(通过指数获得价值) 2.数组可以有重复数据。

3 个答案:

答案 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),其值为键,位置索引为值。