我现在有这样的代码,例如:
list <string> names = {"John", "Peter", "Sarah", "Tom"};
map <string, int> age = {{"John", 64}, {"Peter", 32}, {"Sarah", 24}, {"Tom", 25"};
我需要年龄映射,以便可以在一个点上针对字符串名称查找年龄。而且我需要名称列表,以便可以在其他位置按添加的顺序浏览名称。
因此,有任何方法可以将此功能组合为一个功能,因此我不必重复声明名称字符串,因为两个列表中的名称字符串都相同。但是要保持完全相同的效率吗?
感谢您的帮助。
答案 0 :(得分:6)
这里有很多选项。
不使用名称存储年龄,保留2个不同的列表,并使用共享索引访问名称/年龄对。请记住,对于这一列表,您需要注意列表的大小不要不同,因为这可能会导致一些讨厌的错误。
创建一个包含名称和年龄的结构,并将其存储在容器中(列表,向量等)。
答案 1 :(得分:1)
除非更改相同的元素,否则迭代器永远不会通过更改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;
答案 2 :(得分:1)
您可以创建一个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;
}
另一种方法是使用shared_ptr向量进行排序,并使用一个指向shared_ptr的映射进行索引。这样,您可以更快地从索引访问元素,但是要花费更多的时间在personOrder中查找人员(例如,如果您想删除)。
vector<shared_ptr<Person>> personsOrder;
map<string, shared_ptr<Person>> persons;
void add( string person, int age )
{
personsOrder.push_back( make_shared<Person>(person, 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;
}