如何按类别分组物品并分配数值?寻求优于std::Map的方案
更优的分组分配取值实现方案
你当前用std::map直接存储每个物品与对应数值的方式,会存在数据冗余(比如所有水果都存一遍10),且修改类别数值时需要逐个更新物品条目,效率较低。以下是几种更合理的实现思路:
1. 双层映射结构(推荐通用场景)
建立两个映射表:一个维护类别-数值的对应关系,另一个维护物品-类别的对应关系。这样既避免了数据冗余,又能快速完成物品到数值的查询,还方便批量修改类别数值。
示例代码:
#include <unordered_map> #include <string> // 类别-数值映射 std::unordered_map<std::string, int> category_value = { {"水果", 10}, {"蔬菜", 20}, {"饮料/烘焙", 5} }; // 物品-类别映射 std::unordered_map<std::string, std::string> item_category = { {"Apple", "水果"}, {"orange", "水果"}, {"Mango", "水果"}, {"Potato", "蔬菜"}, {"bag of Carrot", "蔬菜"}, {"Radish", "蔬菜"}, {"Coke", "饮料/烘焙"}, {"Fanta", "饮料/烘焙"}, {"Can of Pepsi", "饮料/烘焙"}, {"Cookie", "饮料/烘焙"}, {"bread", "饮料/烘焙"} }; // 获取物品对应数值的函数 int get_item_value(const std::string& item) { auto cat_it = item_category.find(item); if (cat_it == item_category.end()) { // 处理未找到物品的情况,比如返回默认值或抛出异常 return -1; } auto val_it = category_value.find(cat_it->second); return val_it->second; }
- 优势:新增物品只需在
item_category中添加条目;修改某类数值时,仅需更新category_value中的对应项,无需逐个修改物品条目;查询效率和单map一致(平均O(1))。 - 适用:物品数量较多、类别可能变动的场景。
2. 枚举类+双层映射(类型安全场景)
如果类别是固定的,用枚举类定义类别,能避免字符串类别拼写错误,提升类型安全性。
示例代码:
#include <unordered_map> #include <string> enum class Category { Fruit, Vegetable, BeverageBakery }; std::unordered_map<Category, int> category_value = { {Category::Fruit, 10}, {Category::Vegetable, 20}, {Category::BeverageBakery, 5} }; std::unordered_map<std::string, Category> item_category = { {"Apple", Category::Fruit}, {"orange", Category::Fruit}, // 其他物品映射... }; int get_item_value(const std::string& item) { auto cat_it = item_category.find(item); if (cat_it == item_category.end()) { return -1; } return category_value[cat_it->second]; }
- 优势:编译期就能检查类别是否合法,避免字符串手写错误;性能和内存占用与第一种方案一致。
- 适用:类别固定、对类型安全要求较高的场景。
3. 直接判定函数(简单小规模场景)
如果物品和类别数量都很少,直接写一个判定函数,省去映射表的存储开销,代码更简洁。
示例代码:
#include <string> int get_item_value(const std::string& item) { // 判断物品所属类别 if (item == "Apple" || item == "orange" || item == "Mango") { return 10; } else if (item == "Potato" || item == "bag of Carrot" || item == "Radish") { return 20; } else if (item == "Coke" || item == "Fanta" || item == "Can of Pepsi" || item == "Cookie" || item == "bread") { return 5; } else { // 未找到物品的处理 return -1; } }
- 优势:无需额外存储结构,代码直观,适合快速实现。
- 适用:物品和类别极少、后续几乎不会新增的场景。
内容的提问来源于stack exchange,提问作者Falcon
相关产品推荐
相关产品推荐

