C++ C++;有没有办法以同样的效率将此列表和地图结合起来?

C++ C++;有没有办法以同样的效率将此列表和地图结合起来?,c++,list,dictionary,C++,List,Dictionary,我现在有这样的代码,例如: list <string> names = {"John", "Peter", "Sarah", "Tom"}; map <string, int> age = {{"John", 64}, {"Peter", 32}, {"Sarah", 24}, {"Tom", 25"}; list name={“约翰”、“彼得”、“莎拉”、“汤姆”}; 地图年龄={“约翰”,64},{“彼得”,32},{“萨拉”,24},{“汤姆”,25}; 我需要

我现在有这样的代码,例如:

list <string> names = {"John", "Peter", "Sarah", "Tom"};
map <string, int> age = {{"John", 64}, {"Peter", 32}, {"Sarah", 24}, {"Tom", 25"};
list name={“约翰”、“彼得”、“莎拉”、“汤姆”};
地图年龄={“约翰”,64},{“彼得”,32},{“萨拉”,24},{“汤姆”,25};
我需要年龄图,这样我就可以在某一点上根据字符串名称查找年龄。我还需要姓名列表,这样我就可以在不同的点上按添加的顺序浏览姓名

那么,有没有办法将此功能合并为一个功能,这样我就不必重复名称字符串的声明,因为两个列表中的名称字符串都是相同的。但是,保持完全相同的效率


谢谢您的帮助。

这里有许多选项

  • 不要将年龄与姓名一起存储,保留两个不同的列表,并使用共享索引访问姓名/年龄对。记住,使用此列表时,您需要注意列表的大小不要不同,因为这可能会导致一些严重的错误

  • 创建一个包含名称和年龄的结构,并将其存储在容器(列表、向量等)中


迭代器永远不会因为更改
std::map
结构而失效,除非您删除了相同的精确元素。因此您可以将迭代器存储在
std::vector
中,例如:

std::map<string, int> ages;
std::vector<decltype(ages)::const_iterator> names;

auto pair = ages.emplace(std::make_pair("foo", 25));
names.push_back(pair.first);

std::cout << names[0]->first << " " << names[1]->second << std::endl;
std::地图时代;
std::矢量名称;
自动配对=ages.emplace(std::make_pair(“foo”,25));
姓名。推回(配对第一);

std::cout first您可以创建一个Person结构,保留Person向量,并创建一个映射作为该向量的索引。如果键不唯一,则应使用多重映射。如果需要从Person中删除或插入向量末尾以外的某个位置,则此版本非常慢,因为您必须重新创建personIndex

struct Person {
   string name;
   int age;
};
vector<Person> persons;
map<string, size_t> personIndex;

void add( string person, int age )
{
   persons.emplace_back( person, age );
   personIndex[person] = persons.size() - 1;
}
struct-Person{
字符串名;
智力年龄;
};
媒介人;
地图人格指数;
void add(字符串person,int age)
{
人员。安置(人员、年龄);
personIndex[person]=persons.size()-1;
}
另一种方法是使用shared_ptr向量表示顺序,使用映射到shared_ptr进行索引。这种方法可以从索引中更快地访问元素,但查找personsOrder中的人需要更多时间(例如,如果您想删除)

vectorpersonsorder;
地图绘制人员;
void add(字符串person,int age)
{
人物顺序。推回(使人物、年龄)共享;
persons[person]=personsOrder.back();
}
如果您只是偶尔需要订单,可以将订单存储在Person结构中,然后重新创建订单向量

struct Person {
   string name;
   int age;
   size_t insertOrder;
};
map<string, shared_ptr<Person>> persons;

void add( string person, int age )
{
   persons[person] = make_shared<Person>(person, age, persons.size());
}

vector<string> getOrder()
{
    vector<shared_ptr<Person>> temp;
    for ( auto& person : persons )
       temp.push_back( person->second );

    sort( begin(temp), end(temp), [](auto&& a, auto&& b) { 
       return a->insertOrder < b->insertOrder;
    }

    vector<string> result;
    for ( auto& person : temp )
       result.push_back( person->name );

    return result;
}
struct-Person{
字符串名;
智力年龄;
尺寸插入顺序;
};
地图绘制人员;
void add(字符串person,int age)
{
persons[person]=共享(person,age,persons.size());
}
向量getOrder()
{
向量温度;
用于(自动和人员:人员)
临时推回(人->秒);
排序(开始(临时)、结束(临时),[](自动和a、自动和b){
返回a->insertOrderinsertOrder;
}
矢量结果;
用于(自动和人员:临时)
结果。推回(人员->姓名);
返回结果;
}

?您始终可以将名称存储在向量中(显然您无论如何都需要该向量)然后总是为你所做的每件事引用索引,这样你只存储一次字符串。或者先定义年龄
映射
,然后将键提取到
名称
?关于效率:
std::list
不是一个非常有效的顺序数据结构。它的指定方式几乎肯定是一个链接ed列表。您可以轻松快速地添加和删除,但只要您必须遍历列表,甚至找到插入点或删除点,您就会失败。有时您会以数量级的方式失败。如果您只想要一个有序的列表,其中项目添加到末尾,通常使用
std::vector
效果最好。哦,您是对的。这些已经被删除。谢谢!一些好的建议,但我还是用了第一个建议,向量到结构。谢谢大家。
struct Person {
   string name;
   int age;
   size_t insertOrder;
};
map<string, shared_ptr<Person>> persons;

void add( string person, int age )
{
   persons[person] = make_shared<Person>(person, age, persons.size());
}

vector<string> getOrder()
{
    vector<shared_ptr<Person>> temp;
    for ( auto& person : persons )
       temp.push_back( person->second );

    sort( begin(temp), end(temp), [](auto&& a, auto&& b) { 
       return a->insertOrder < b->insertOrder;
    }

    vector<string> result;
    for ( auto& person : temp )
       result.push_back( person->name );

    return result;
}