C++ 有没有办法以相同的效率组合此列表和映射



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

list <string> names = {"John", "Peter", "Sarah", "Tom"};
map <string, int> age = {{"John", 64}, {"Peter", 32}, {"Sarah", 24}, {"Tom", 25"};

我需要年龄图,以便我可以在某一时刻根据字符串名称查找年龄。我需要名称列表,以便我可以在不同的点按添加的顺序浏览名称。

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

感谢您的帮助。

这里有许多选项可用。

  • 不要将年龄与名称一起存储,保留 2 个不同的列表并使用共享索引访问名称/年龄对。请记住,对于这个,您需要注意列表没有不同的大小,因为这可能会导致一些令人讨厌的错误。

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

您可以创建一个 Person 结构并保留 Person 向量,并创建一个映射作为该向量的索引。如果键不是唯一的,则应使用多重映射。如果您需要从 people 中删除或插入不在向量末尾的某个地方,则此版本非常慢,因为您必须重新创建 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进行索引。通过这种方式,您可以更快地从索引中访问元素,但是在 personsOrder 中找到该人员需要更多时间(例如,如果您想删除(。

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

器永远不会通过更改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;

最新更新