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

时间:2019-06-14 15:38:51

标签: c++ list dictionary

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

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

我需要年龄映射,以便可以在一个点上针对字符串名称查找年龄。而且我需要名称列表,以便可以在其他位置按添加的顺序浏览名称。

因此,有任何方法可以将此功能组合为一个功能,因此我不必重复声明名称字符串,因为两个列表中的名称字符串都相同。但是要保持完全相同的效率吗?

感谢您的帮助。

3 个答案:

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