0

我想获得搜索名称的第一个位置和最后一个位置。

我无法编译这段代码,尽管我已经看到了类似的指令正在执行。在lower_bound 和upper_bound 中给出错误。

用 C++11 编译

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

using namespace std;

class Client
{
public:
    int id;
    string name;
    int number;
};

int main()
{
    vector<Client>::iterator low;
    vector<Client>::iterator up;
    string s_name;

    Client c1;
    c1.id = 1;
    c1.name = "jhon";
    c1.number = 123;

    Client c2;
    c2.id = 2;
    c2.name = "Mart";
    c2.number = 987;

    Client c3;
    c3.id = 3;
    c3.name = "Jhon";
    c3.number = 256;

    Client c4;
    c4.id = 4;
    c4.name = "Anna";
    c4.number = 851;

    vector<Client> vCli{c1, c2, c3, c4};

    sort(vCli.begin(), vCli.end(), [](Client a, Client b) { return a.name < b.name; });

    s_name = "Jhon";

    low = lower_bound(vCli.begin(), vCli.end(), s_name, [](Client a, Client b) { return a.name < b.name; });
    up = upper_bound(vCli.begin(), vCli.end(), s_name, [](Client a, Client b) { return a.name < b.name; });

    cout << (low - vCli.begin()) << endl;
    cout << (up - vCli.begin()) << endl;

    return 0;
}
C:\Program Files (x86)\CodeBlocks\MinGW\lib\gcc\mingw32\5.1.0\include\c++\bits\predefined_ops.h|144|
error: no match for call to '(main()::<lambda(Client, Client)>) (Client&, const std::__cxx11::basic_string<char>&)'|
4

3 回答 3

2

std::lower_boundand的第三个参数std::upper_bound必须是Client对象或可以转换为Client. 如果您添加一个Client允许您Client从 astd::string隐式构造的构造函数,则您的代码将起作用。这是一个快速修复,不需要对您的代码进行任何其他更改。

Client s;
s.name =  "Jhon";

low = lower_bound (vCli.begin(), vCli.end(), s, [](Client a, Client b) { return a.name <  b.name; });
up  = upper_bound (vCli.begin(), vCli.end(), s, [](Client a, Client b) { return a.name <  b.name; });
于 2019-11-25T21:19:17.967 回答
1

给你。

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

class Client
{ 
public:
    int id;
    std::string name;
    int number; 
};

int main() 
{
    std::vector<Client> vCli =
    {
        { 1, "Jhon", 123 },
        { 2, "Mart", 987 },
        { 3, "Jhon", 256 },
        { 4, "Anna", 851 },
    };

    std::sort( std::begin( vCli ), std::end( vCli ),
               []( const Client &c1, const Client &c2 )
               {
                    return c1.name < c2.name; 
               } );

    std::string s_name = "Jhon";

    auto low = std::lower_bound( std::begin( vCli ), std::end( vCli ), s_name,
                                []( const Client &c, const std::string &s )
                                {
                                    return c.name < s;
                                } );

    auto up = std::upper_bound( std::begin( vCli ), std::end( vCli ), s_name,
                                []( const std::string &s, const Client &c )
                                {
                                    return s < c.name;
                                } );

    for ( auto first = low; first != up; ++first )
    {
        std::cout << first->id << ", "  
                  << first->name << ", "
                  << first->number << '\n';
    }


    return 0;
}

程序输出为

1, Jhon, 123
3, Jhon, 256

而不是单独调用std::lower_boundandstd::upper_bound你可以使用一个调用std::equal_range. 在这种情况下,您应该定义一个函数对象,如下面的演示程序所示

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

class Client
{ 
public:
    int id;
    std::string name;
    int number; 
};

struct Compare_by_name
{
    bool operator ()( const Client &c, const std::string &s ) const
    {
        return c.name < s;
    }

    bool operator ()( const std::string &s, const Client &c ) const
    {
        return s < c.name;
    }
};

int main() 
{
    std::vector<Client> vCli =
    {
        { 1, "Jhon", 123 },
        { 2, "Mart", 987 },
        { 3, "Jhon", 256 },
        { 4, "Anna", 851 },
    };

    std::sort( std::begin( vCli ), std::end( vCli ),
               []( const Client &c1, const Client &c2 )
               {
                    return c1.name < c2.name; 
               } );

    std::string s_name = "Jhon";

    auto low_up = std::equal_range( std::begin( vCli ), std::end( vCli ), s_name,
                                    Compare_by_name() );   


    for ( auto first = low_up.first; first != low_up.second; ++first )
    {
        std::cout << first->id << ", "  
                  << first->name << ", "
                  << first->number << '\n';
    }


    return 0;
}

您也可以使用此函数对象来std::lower_bound代替std::upper_bound它们的 lambda 表达式。

于 2019-11-25T21:52:13.653 回答
1

当您在比较器中搜索std::string一个参数时,该参数必须是 astd::string而非 a Client

low = lower_bound(vCli.begin(), vCli.end(), s_name, [](const Client& a, const std::string& b) { return a.name < b; });
up = upper_bound(vCli.begin(), vCli.end(), s_name, [](const std::string& a, const Client& b) { return a < b.name; });
于 2019-11-25T21:53:34.603 回答