Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从std::vector获取特定结构对象的快速方法_C++_C++11_Vector_Struct - Fatal编程技术网

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
,因为一旦设置好容器及其对象,我很可能不会更改它们。