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;
}