如何使用lower_bound将值插入排序向量

How to use lower_bound to insert value into sorted vector

本文关键字:插入排序 向量 bound 何使用 lower      更新时间:2023-10-16

我有一个指向类a的指针向量,我想用STL按int键排序。为此,我在类A

中定义了一个operator <
bool operator< (const A &lhs, const A &rhs){
    return (lhs.key < rhs.key);
};

在我的插入函数中它看起来像

vector<A*>::iterator it = lower_bound(vec.begin(), vec.end(), element);
vec.insert(it, element);

我期望lower_bound返回可以放置新元素的第一个位置,但它不起作用。插入键为0、1、2、3的A对象将导致向量的顺序不正确(2、3、1、0)。为什么?

也许我也可以为这个对象使用comparator:

upper_bound/lower_bound的比较函数

但是我的代码有什么问题?

从您的示例中,您正在使用指针向量:std::vector<A*>。因此,需要为传递给std::lower_bound的指针定义一个比较:

bool less_A_pointer (const A* lhs, const A* rhs)
{
    return (lhs->key < rhs->key);
}
auto it = std::lower_bound(vec.begin(), vec.end(), element, less_A_pointer);
//...

当然,问题是为什么首先要使用指针——除非真的需要,否则只存储A对象。如果你确实需要存储指针,请查看std::shared_ptr,它将为你处理这个问题:

std::vector<std::shared_ptr<A>> v;
std::shared_ptr<A> element(new A(...));
auto it = std::lower_bound(v.begin(), v.end(), element); //Will work properly

您也可以使用lambda而不必编写自由函数:

auto it = std::lower_bound(v.begin(), v.end(), 
                          [](const A* lhs, const A* rhs)
                          { return lhs->key < rhs->key; });

如果你真的想要一个std::vector的指针,你可以考虑使用一个智能指针,比如std::shared_ptr
如果观察指针,则Raw指针是可以的,但通常情况下,您不应该使用Raw拥有的指针(除非在某些特殊情况下)。

您可以将lambda传递给std::lower_bound(),以指定排序标准(在本例中,比较关键数据成员)。

此外,您可以使用c++ 11的auto关键字,而不是为std::lower_bound()的返回值显式地编写std::vector<std::shared_ptr<A>>::iterator,这使得代码在这种情况下更具可读性。

下面是一个可编译的代码示例(使用g++ 4.8.0编译):
#include <algorithm>    // for std::lower_bound
#include <iostream>     // for console output
#include <memory>       // for std::make_shared, std::shared_ptr
#include <string>       // for std::string
#include <vector>       // for std::vector
using namespace std;
// Test data structure
struct A
{
    int Key;
    string Data;
    A()
        : Key(0)
    {}
    A(int key, const string& data)
        : Key(key), Data(data)
    {}
};
ostream& operator<<(ostream& os, const A& a)
{
    os << "(key=" << a.Key << ", data="" << a.Data << "")";
    return os;
}
void Print(const vector<shared_ptr<A>> & v)
{
    cout << "[ ";
    for (const auto & p : v)
    {
        cout << *p << " ";
    }
    cout << " ]n";
}
int main()
{
    // Test container
    vector<shared_ptr<A>> v;
    // Test data
    const char* data[] = {
        "hello",
        "world",
        "hi",
        nullptr
    };
    // Index in data array
    int i = 0;
    // Insertion loop
    while (data[i] != nullptr)
    {
        // Create new element on the heap
        auto elem = make_shared<A>(i, data[i]);
        // Find ordered insertion position
        auto it = lower_bound(v.begin(), v.end(), elem,
            [](const shared_ptr<A>& lhs, const shared_ptr<A>& rhs)
            {
                return lhs->Key < rhs->Key;
            }
        );
        // Insert in vector
        v.insert(it, elem);
        // Move to next data
        i++;
    }
    // Show the result
    Print(v);
}

输出如下:

[ (key=2, data="hi") (key=1, data="world") (key=0, data="hello")  ]