对的向量:第一对值是非排序的,第二对值是排序的:如何在具有未排序的值时找到排序的值

时间:2015-04-07 18:44:36

标签: c++ sorting find stdvector std-pair

我有一对对矢量,如下所示。第一对值是未排序的,第二对值是排序的(从零开始)。我可能希望通过实施std::vectorstd::pair来存储数据。当我有第一对值(未排序)时,找到相应的第二对值(已排序)的最佳方法是什么?实现它的最佳方法是什么?

另一种方式是直观的:当我有第二对值(排序,从零开始)时,我可以很容易地找到相应的第一对值(未排序)。

enter image description here

1 个答案:

答案 0 :(得分:1)

当第二个值被排序时,您可以执行二进制搜索。 (如果没有排序,你可以使用线性的std::find_if

要执行二进制搜索,您需要使用std::lower_bound,这很棘手。你需要提供一个函子来告诉它你的向量是如何排序的,在这种情况下是第二个值。如果找到该值,则返回一个迭代器。如果它没有找到该值,它会将迭代器返回到另一个值或结束迭代器。 if语句检查end iterator first ,因为它取消引用结束迭代器是无效的。

如果你的矢量没有按第二个值排序,那么这不会起作用。您可能希望断言它首先排序,以避免发生意外。

提供给std::lower_bound的仿函数只需要第二个参数的密钥类型(搜索时,第一对值不会形成密钥)。但要断言它是有序的,两个参数都必须是存储在向量中的类型。

std::vector<std::pair<T1, T2>> data;
T2 find_val;

// check the vector is sorted properly
assert(std::is_sorted(data.begin(), data.end(), [](const std::pair<T1, T2>& left, const std::pair<T1, T2>& right){ return left.second < right.second; }));

// attempt to find our value
auto find_it = std::lower_bound(data.begin(), data.end(), find_val, [](const std::pair<T1, T2>& left, const T2& right){ return left.second < right; });

// check it's not the end iterator and it actually points to our value
if (find_it != data.end() && find_it->second == find_val)
{
    // found it!
    auto& retrieve_val = find_it->first;
}
else
{
    // not found
}

以下是使用std::find_if的示例,这是一个线性搜索,但不关心向量是否已排序。

auto find_it = std::find_if(data.begin(), data.end(), [&find_val](const std::pair<T1, T2>& val){ return val.second == find_val; });

if (find_it != data.end())
{
    // found it!
    auto& retrieve_val = find_it->first;
}
else
{
    // not found
}