如何在std :: binary_search中设置针类型

时间:2015-07-06 07:50:25

标签: c++ algorithm search

我有以下简单程序,它将对项目进行binary_search:

#include <vector>
#include <algorithm>
#include <string>
#include <iostream>

class Record
{
public:
    Record() = default;
    Record(std::string name, int data) : mName(name), mData(data) { }
    std::string mName;
    int mData = 0;
};

int main(int, char**)
{
    std::vector<Record> recs;

    recs.emplace_back(Record("1", 1));
    recs.emplace_back(Record("55555", 2));
    recs.emplace_back(Record("333", 3));
    recs.emplace_back(Record("qwertyuiop", 4));
    recs.emplace_back(Record("22", 5));
    recs.emplace_back(Record("4444", 6));

    std::cout << "Unsorted:" << std::endl;
    for (auto& rec : recs)
    {
        std::cout << "Name: "  << rec.mName << " Data: " << rec.mData << std::endl;
    }
    std::cout << std::endl;

    std::stable_sort(recs.begin(), recs.end(), [](const Record& lhs, const Record& rhs) -> bool
    {
        return lhs.mName.length() < rhs.mName.length();
    });

    std::cout << "Sorted:" << std::endl;
    for (auto& rec : recs)
    {
        std::cout << "Name: " << rec.mName << " Data: " << rec.mData << std::endl;
    }
    std::cout << std::endl;

    if (std::binary_search(
        recs.begin(), 
        recs.end(),
        Record("qwertyuiop", 4),
        [](const Record& lhs, const Record& rhs) -> bool 
    {
        return lhs.mName < rhs.mName;
    }))
    {
        std::cout << "Found" << std::endl;
    }
    else
    {
        std::cout << "Not found" << std::endl;
    }


    return 0;
}

如何根据其他类型的T搜索记录向量?例如std :: string而不是Record?

类似的东西:

 if (std::binary_search(
            recs.begin(), 
            recs.end(),
            "qwertyuiop",
            [](const Record& lhs, const std::string& rhs) -> bool 
        {
            return lhs.mName < rhs.mName;
        }))
        {
            std::cout << "Found" << std::endl;
        }
        else
        {
            std::cout << "Not found" << std::endl;
        }

是我想要的 - 基本上我不想构建一个Record来搜索它,因为这会给我带来性能问题。

2 个答案:

答案 0 :(得分:3)

您可以创建一个处理异构比较的函数对象类型:

struct comp_t
{
    bool operator()(Record const& lhs, std::string const& rhs) const {
        return lhs.mName < rhs;
    }

    bool operator()(std::string const& lhs, Record const& rhs) const {
        return lhs < rhs.mName;
    }
};

然后你可以这样打电话给binary_search

std::binary_search(recs.begin(), recs.end(),
                   std::string("qwertyuiop"),
                   comp_t{})

答案 1 :(得分:0)

您可以通过添加implicit构造函数将std::string转换为Record以及将Record转换为std::string的运算符来实现此目的。

operator std::string() const {
    return mName;
}

Record(std::string name) : mName(name), mData(int()) {}

或者您可以将现有构造函数转换为此

Record(std::string name, int data = int()) : mName(name), mData(data) {}

但无论如何,您需要创建一个std::string对象进行搜索。

/// create std::string object from "qwertyuiop"
if (std::binary_search(recs.begin(), recs.end(), std::string("qwertyuiop"), 
    [](const Record & lhs, const std::string & rhs) -> bool 
        {
            return lhs.mName < rhs;    /// rhs is a std::string type
        })) {
    std::cout << "Found" << std::endl;
}
else {
    std::cout << "Not found" << std::endl;
}

请参阅http://ideone.com/0f16GE演示。