C++ 从std::vector获取特定结构对象的快速方法
我有一个简单的C++ 从std::vector获取特定结构对象的快速方法,c++,c++11,vector,struct,C++,C++11,Vector,Struct,我有一个简单的struct称为项 struct Item { unsigned int id; std::string name; Item() : id( 0 ), name( std::string( "" ) ) { }; }; 然后我有这个类来保存所有这些项 class ItemData { public: std::vector< Item > m_Items; private: void load() {
struct
称为项
struct Item {
unsigned int id;
std::string name;
Item() : id( 0 ), name( std::string( "" ) ) {
};
};
然后我有这个类来保存所有这些项
class ItemData {
public:
std::vector< Item > m_Items;
private:
void load() {
// Parse a JSON string to fill up m_Items vector with
// Item objects.
}
const Item getItem( unsigned int pID ) {
// Create an "empty" Item object with ID = 0 and name = ""
Item temp = Item();
// Loop through the vector
for ( unsigned int i = 0; i < m_Items.size(); i++ ) {
// Check if the current Item object has the id we are looking for
if ( m_Items.at( i ).id == pID ) {
// The item is inside the vector, replace temp with the
// target vector
temp = m_Items.at( i );
// Stop looping
break;
}
}
// If pID was found, temp will have the values of the object inside the vector
// If not, temp will have id = 0 and name = ""
return temp;
}
};
类ItemData{
公众:
标准::向量- m_项;
私人:
空荷载(){
//解析JSON字符串以填充m_Items向量
//项目对象。
}
常量项getItem(无符号整数pID){
//创建一个ID=0且name=“”的“空”项目对象
项目温度=项目();
//循环遍历向量
for(无符号整数i=0;i
我觉得这个方法花费了太多时间,尤其是在循环中调用ItemData::getItem(unsigned int)
时
有没有一种更有效的方法可以在向量中获取对象,而不必在向量中循环?我是否应该使用不同的容器(例如std::list
)使用std::map
:
class ItemData {
public:
std::map<unsigned, Item> m_Items;
private:
void load() {
// Parse a JSON string to fill up m_Items vector with
// Item objects.
}
const Item getItem(unsigned id) const {
std::map<unsigned, Item>::const_iterator it = m_Items.find(id);
if (it != m_Items.end())
return it->second;
return Item();
}
};
类ItemData{
公众:
标准::地图m_项目;
私人:
空荷载(){
//解析JSON字符串以填充m_Items向量
//项目对象。
}
常量项getItem(未签名id)常量{
std::map::const_迭代器it=m_Items.find(id);
if(it!=m_Items.end())
返回->秒;
退货项目();
}
};
你可以考虑<代码> STD::unOrdEdEdMult。
如果你只想遍历容器中的所有项,那么向量是很棒的。如果在线性搜索不影响性能的情况下,查找频率相对较低,那么向量可能仍然可以
如果您需要能够根据项目id查找项目,而不关心保留项目在容器中的插入顺序,则根据您的排序需要、容器大小等,使用map
或unordered\u map
如果您需要维护插入顺序并按id快速查找,并且不会从向量中删除项目,那么我建议使用id到索引的无序映射
,并在添加新项目时维护id索引映射。绝对不是std::list
。我相信您正在寻找std::map
(它将唯一ID映射到对象)。或者可以使用自定义比较器设置std::set
(仅存储唯一对象),以便根据项的id
对项进行比较
set
的缺点是将对象存储为const
。我相信map
最适合您(将id
一次存储为map键,一次存储在项中的开销很低)
我想保留插入顺序以及快速查找,但可能不需要删除项目
所以你要做的是为向量建立一个索引。即创建一个哈希表,将项目id映射到向量中的项目位置:
class ItemData {
vector< Item > m_Items;
unordered_map<unsigned int, size_t> m_ItemsIndex;
void prepare_index()
{
for (size_t i = 0; i < m_Items.size(); i++)
m_ItemsIndex[m_Items[i].id] = i;
}
Item& get_item(unsigned int id)
{
size_t pos = m_ItemsIndex[id];
return m_Items[pos];
}
}
类ItemData{
向量- m_项;
无序地图m_ItemsIndex;
void prepare_index()
{
对于(size_t i=0;i
这将查找速度从线性(O(n))提高到恒定时间(O(1))
在load
末尾调用prepare\u index
。您还需要添加错误检查等,但您已经明白了
插入顺序被保留,因为您仍然可以直接迭代向量。您的ID有哪些示例?对于不同的容器,std::map
的查找时间为O(logn)。@DarkFalcon ID只是无符号整数<代码>0
、1
、176
、2000
是一些有效的ID。name(std::string(“”)
是完全冗余的。getItem
是粗略的。首先,你正在重新发明轮子<如果您提供了一个函子(或C++11中的lambda),那么代码>标准::find
可以为您实现这一点。另一方面,getItem
不仅仅获取项目。它找到它,然后替换它。简单总比复杂好。@JohnDibling:你说“它取代了它”是什么意思?我想保留插入顺序和快速查找,但可能不需要删除项目。@LanceGray:我根据你在回答中的评论提出了一个解决方案。我对
有点困惑。我可以看出,unsigned
将是每个项
对象的键,但是unsigned
不应该是unsigned int
?或者它们是相同类型的?@LanceGray是的,它们是相同的。这是编写无符号int
的一个很好的理由。好的,你保存了四次击键:做得好!但是,你因此扼杀了clarity。我不介意我的对象是const
,因为一旦设置好容器及其对象,我很可能不会更改它们。