到目前为止,我一直将数组存储在向量中,然后通过循环遍历向量以查找匹配的元素,然后返回索引。
C ++ 中是否有更快的方法? 我用于存储数组的STL结构对我来说并不重要(它不必是向量)。 我的数组也是唯一的(没有重复的元素)和有序的(例如,一组随时间推移而前进的日期列表)。
由于元素已经排序,您可以使用二分查找来查找匹配的元素。C++标准库有一个std::lower_bound
算法可用于此目的。我建议将其包装在自己的二分查找算法中,以便更清晰简单:
/// Performs a binary search for an element
///
/// The range `[first, last)` must be ordered via `comparer`. If `value` is
/// found in the range, an iterator to the first element comparing equal to
/// `value` will be returned; if `value` is not found in the range, `last` is
/// returned.
template <typename RandomAccessIterator, typename Value, typename Comparer>
auto binary_search(RandomAccessIterator const first,
RandomAccessIterator const last,
Value const& value,
Comparer comparer) -> RandomAccessIterator
{
RandomAccessIterator it(std::lower_bound(first, last, value, comparer));
if (it == last || comparer(*it, value) || comparer(value, *it))
return last;
return it;
}
std::map
或std::unordered_map
。根据你想在数据上执行的其他操作,还可以将它们与其他数据结构(例如std::list
或std::vector
)组合使用。vector<int> test(test_size);
unordered_map<int, size_t> lookup;
int value = 0;
for(size_t index = 0; index < test_size; ++index)
{
test[index] = value;
lookup[value] = index;
value += rand()%100+1;
}
size_t index = lookup[find_value];
使用基于哈希表的数据结构(例如unordered_map)是一种相对经典的时空权衡方法,在需要进行大量查找的"反向"查找操作时,可以超越二分查找的性能。另一个优点是,它也适用于未排序的向量。
为了好玩:-)我在VS2012RC中进行了一个快速比较,将James的二分查找代码与线性查找和使用unordered_map进行查找,全部应用于一个向量:
在大约50000个元素的情况下,unordered_set明显优于二分查找(3-4倍),而二分查找表现出预期的O(log N)行为,有些意外的是,unordered_map失去了其在10000个元素以上的O(1)行为,可能是由于哈希冲突或实现问题所致。
编辑:unordered_map的max_load_factor()为1,因此不应该存在冲突。对于非常大的向量,二分查找和哈希表之间的性能差异似乎与缓存相关,并且取决于基准测试中的查找模式。
选择 std::map 还是 std::unordered_map 介绍了有序和无序 map 的区别。