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

Posted

技术标签:

【中文标题】如何在 std::binary_search 中设置针类型【英文标题】:How to set needle type in std::binary_search 【发布时间】:2015-07-06 07:50:24 【问题描述】:

我有以下简单的程序,它将二进制搜索一个项目:

#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 搜索 Records 的向量?例如 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;
        

是我想要的 - 基本上我不想构建记录来搜索它,因为这对我来说是一个性能问题。

【问题讨论】:

我想不出使用标准库的方法。我会自己实现二进制搜索 - 大约 10 行代码 【参考方案1】:

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

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)

【讨论】:

【参考方案2】:

您可以通过添加一个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 演示。

【讨论】:

以上是关于如何在 std::binary_search 中设置针类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Netbeans 中设置环境变量?

如何在 Android 中设置 libsvm?

如何在 Laravel 中设置全局变量?

如何在代码中设置绑定?

如何在协议扩展中设置委托

如何在预览中设置环境对象