I would like to getting the first position and last position of the searched name.
I can't compile this code, although I've seen similar instructions being executed. Gives an error in lower_bound and upper_bound.
Compiled in 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>&)'|
The third argument to std::lower_bound
and std::upper_bound
has to be a Client
object or something that can be converted to a Client
. If you add a constructor in Client
that allows you to construct a Client
from a std::string
implicitly, your code would work. Here's a quick fix that does not require any other changes to your code.
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; });
Here you are.
#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;
}
The program output is
1, Jhon, 123
3, Jhon, 256
Instead of separate calls of std::lower_bound
and std::upper_bound
you could use one call of std::equal_range
. In this case you should define a function object as shown in the demonstrative program below
#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;
}
This function object you can use also with std::lower_bound
and std::upper_bound
instead of their lambda expressions.
As you are searching for a std::string
one argument in your comparator needs to be a std::string
not 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; });
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.