如何使用 binary_search STL 函数在嵌套类中搜索整数?

How to search for an integer within a nested class with the binary_search STL function?

本文关键字:嵌套 搜索 整数 函数 binary 何使用 search STL      更新时间:2023-10-16

如何使用binary_searchSTL函数在嵌套类中搜索整数?是否可以对向量vITems进行二叉搜索以搜索产品类别 ID?目前,我必须在Order类中填充一个std::vector<Product> vProd数组才能使用binary_search函数。

我在这个问题上做了很多研究,但我没有成功地解决这个问题。

#include <iostream>
#include <algorithm>
#include <vector>
class Product {
public:
int Id;
std::string Name;
Product(int idProd, const std::string &nameProd) : Id(idProd), Name(nameProd) {}
Product(int idProd) : Id(idProd)  {} // Required for lambda function to work on binary_search function
};
class Item {
public:
Product Prod;
int Number;
Item(Product &prod, int numProd) : Prod(prod), Number(numProd) {}
};
class Order{
private:
std::vector<Item> vItems;
public:
bool consultProd(int idProd) const {
std::vector<Product> vProd;
size_t total = vItems.size();
for(size_t i = 0; i < total; i++)
vProd.push_back(vItems[i].Prod);

bool yesId = binary_search( vProd.begin(), vProd.end(), idProd,
[]( const Product &p1, const Product &p2)
{
return p1.Id < p2.Id;
} );
return yesId;
}

void setItem(Item &it){
vItems.push_back(it);
}
};

int main()
{
//----------------------------------------------------------------
Product p1(1, "aaa"), p2(2, "bbb"), p3(3, "ccc"), p4(4, "ddd");
Item it1(p1, 1), it2(p2, 3), it3(p3, 3), it4(p4, 7);
Order ord;
ord.setItem(it1);
ord.setItem(it2);
ord.setItem(it3);
ord.setItem(it4);
//----------------------------------------------------------------
if( !ord.consultProd(2) )
ord.setItem(it2);
else
std::cout << "Warning: Product already included in the order.n";
system("pause");

return 0;
}

带助手:

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

您可以使用自定义比较器:

bool consultProd(int idProd) const {
return binary_search(
vItems.begin(),
vItems.end(),
idProd,
overloaded{[](int id, const Item& item) { return id < item.Prod.Id; },
[](const Item& item, int id) { return item.Prod.Id < id; }
});
}

演示

您可以使用std::lower_bound

const auto item_it = std::lower_bound(vItems.begin(), vItems.end(), idProd,
[](const Item& item, int id) { return item.Prod.Id < id; });
const bool yesId = (item_it != vItems.end() && item_it->Prod.Id == idProd);
return yesId;

请注意,[vItems.begin(), vItems.end())应表示按Prod.Id排序或至少相对于Prod.Id < idProd分区的有效项目范围。如果不满足此条件,则std::lower_bound的行为是不确定的。


进行此排序的正确方法是什么?

如果范围没有排序,正确的方法是使用std::find_if

const auto item_it = std::find_if(vItems.begin(), vItems.end(), 
[idProd](const Item& item) { return item.Prod.Id == idProd; });
const bool yesId = (item_it != vItems.end());

在每次二叉搜索之前进行排序没有意义:二叉搜索需要O(log n)时间,但排序需要O(n log n)时间。这比std::find_if提供的线性时间复杂度O(n)更差。