按Ingredient.name
搜索时,我需要FindIngredient
返回一个const Ingredient &
。我需要使用unordered_set
。所以我想我需要其中的两个,一个包含对象,另一个只包含字符串属性name
,以便按字符串搜索。
我的方法可以吗?或者我只使用unordered_set<Ingredient> ingredients
就可以实现吗?
按照我的方法,我如何在FindIngredient
函数中返回?我想返回ingredients
中的对象,其属性名称是在ingredientsByName
中搜索到的对象
class Ingredient {
public:
string Name;
int Price;
string Description;
};
class Pizzeria {
unordered_set<string> ingredientsByName;
unordered_set<Ingredient> ingredients;
public:
void AddIngredient(const string &name, const string &description, const int &price)
{
if(ingredientsByName.find(name) == ingredients.end())
{
throw "Ingredient already inserted";
}
else
{
Ingredient ingredient;
ingredient.Name = name;
ingredient.Price = price;
ingredient.Description = description;
ingredients.insert(ingredient);
ingredientsByName.insert(ingredient.Name);
ingredients.insert(ingredient);
}
}
const Ingredient &FindIngredient(const string &name) const
{
if(ingredientsByName.find(name) == ingredients.end())
{
throw "Ingredient not found";
}
else
{
return // how Do I return the corresponding Ingredient ???
}
}
}
如果你不介意较慢的搜索算法(O(N)
时间(,那么你可以做一个简单的循环:
for (auto it = ingredients.begin(); it != ingredients.end(); ++it)
if (it->Name == name)
return *it; // Return found ingredient.
throw "Ingredient not found";
上面的循环可以更短:
for (auto const & e: ingredients)
if (e.Name == name)
return e; // Return found ingredient.
throw "Ingredient not found";
如果您想要快速搜索算法(O(Log N)
时间(,则可以使用std::unordereded_map,即:
unordered_map<string, Ingredient> ingredientsByName;
添加到地图:
ingredientsByName[ingredient.Name] = ingredient;
然后在里面搜索:
auto it = ingredientsByName.find(name);
if (it == ingredientsByName.end())
throw "Ingredient not found";
return it->second; // Returns found ingredient.
如果您需要元素的排序顺序(按键(,那么您可以使用std::map而不是std::unordered_map,map总是按键排序(但在搜索和插入数千个元素时慢2-5倍(,而unordered_map总是未排序(但搜索和插入时快2-5倍(。
如果您想单独储存成分,则可以使用std::shared_ptr:
unordered_map<string, shared_ptr<Ingredient>> ingredientsByName;
vector<shared_ptr<Ingredient>> ingredients;
// Adding element:
shared_ptr<Ingredient> ingredient = make_shared<Ingredient>();
ingredient->Name = "abc";
// Also fill other fields.
ingredients.push_back(ingredient);
ingredientsByName[ingredient->Name] = ingredient;
// Search:
auto it = ingredientsByName.find(name);
if (it == ingredientsByName.end())
throw "Ingredient not found";
return *it->second; // Returns found ingredient.
您可以将std::find_if
与合适的lambda函数一起使用,以使用Ingredient
的Name
成员进行查找。
您需要将结果保存在一个变量中,以便在返回时使用。
也许是这样的:
const Ingredient &FindIngredient(const string &name) const
{
auto result = std::find_if(begin(ingredients), end(ingredients), [&name](Ingredient const& ingredient)
{
return ingredient.Name == name;
});
if (result == end(ingredients))
{
throw "Ingredient not found";
}
return *result;
}