C++ STL map我不想让它排序!

Pra*_*are 23 c++ stl

这是我的代码

map<string,int> persons;

persons["B"] = 123;
persons["A"] = 321;


for(map<string,int>::iterator i = persons.begin();
    i!=persons.end();
    ++i)
{
    cout<< (*i).first << ":"<<(*i).second<<endl;
}
Run Code Online (Sandbox Code Playgroud)

预期产量:

  B:123
  A:321
Run Code Online (Sandbox Code Playgroud)

但它给出的输出是:

  A:321
  B:123
Run Code Online (Sandbox Code Playgroud)

我希望它保持键中插入键和值的顺序map<string,int>.

可能吗?或者我应该使用其他一些STL数据结构?哪一个?

小智 37

没有标准容器可以直接执行您想要的操作.如果要维护插入顺序,要使用的明显容器是向量.如果您还需要按字符串查找,请使用矢量和地图.地图通常是字符串到矢量索引,但由于您的数据已经是整数,您可能只想复制它,具体取决于您的用例.

  • @Hassan但是vector(和deque)是在尾部添加的分摊的常量时间,通常比列表更快,允许随机访问并占用更少的内存.正如我之前所说,列表应该是最后的选择,而不是第一个. (8认同)
  • 像往常一样:如果你需要一个没有任何特殊要求的容器,你需要一个`vector`. (2认同)

Man*_*uel 20

就像Matthieu在另一个回答中所说,Boost.MultiIndex库似乎是您想要的正确选择.但是,这个库在开始时可能有点难以使用,特别是如果你没有很多C++经验的话.以下是如何使用库来解决问题代码中的确切问题:

struct person {
    std::string name;
    int id;
    person(std::string const & name, int id) 
    : name(name), id(id) { 
    }
};

int main() {

    using namespace::boost::multi_index;
    using namespace std;

    // define a multi_index_container with a list-like index and an ordered index
    typedef multi_index_container<
      person,        // The type of the elements stored
      indexed_by<    // The indices that our container will support
        sequenced<>,                           // list-like index
        ordered_unique<member<person, string, 
                              &person::name> > // map-like index (sorted by name)
      >
    > person_container;

    // Create our container and add some people
    person_container persons;
    persons.push_back(person("B", 123));
    persons.push_back(person("C", 224));
    persons.push_back(person("A", 321));

    // Typedefs for the sequence index and the ordered index
    enum { Seq, Ord };
    typedef person_container::nth_index<Seq>::type persons_seq_index;
    typedef person_container::nth_index<Ord>::type persons_ord_index;

    // Let's test the sequence index
    persons_seq_index & seq_index = persons.get<Seq>();
    for(persons_seq_index::iterator it = seq_index.begin(), 
                                    e = seq_index.end(); it != e; ++it)
        cout << it->name << ":"<< it->id << endl;
    cout << "\n";

    // And now the ordered index
    persons_ord_index & ord_index = persons.get<Ord>();
    for(persons_ord_index::iterator it = ord_index.begin(), 
                                    e = ord_index.end(); it != e; ++it)
        cout << it->name << ":"<< it->id << endl;
    cout << "\n";

    // Thanks to the ordered index we have fast lookup by name:
    std::cout << "The id of B is: " << ord_index.find("B")->id << "\n";
}
Run Code Online (Sandbox Code Playgroud)

其中产生以下输出:

B:123
C:224
A:321

A:321
B:123
C:224

The id of B is: 123
Run Code Online (Sandbox Code Playgroud)


Pét*_*rök 9

地图绝对不适合你:

"在内部,地图中的元素按照在构造上设置的特定严格弱排序标准从较低到较高的键值排序."

引用取自这里.

不幸的是,STL中没有无序的关联容器,所以你要么使用非关联容器,要么vector自己编写:-(

  • 现在(使用C++ 11),_is_是标准库中的无序关联容器.它被称为std :: unordered_map,但unordered_map无法解决问题,因为它不保留插入顺序,这是原始问题的内容. (2认同)

Nie*_*ann 5

我每隔一段时间都会遇到同样的问题,这是我的解决方案:https : //github.com/nlohmann/fifo_map。这是一个仅包含头文件的 C++11 解决方案,可用作std::map.

对于您的示例,它可以按如下方式使用:

#include "fifo_map.hpp"
#include <string>
#include <iostream>

using nlohmann::fifo_map;

int main()
{
    fifo_map<std::string,int> persons;

    persons["B"] = 123;
    persons["A"] = 321;

    for(fifo_map<std::string,int>::iterator i = persons.begin();
        i!=persons.end();
        ++i)
    {
        std::cout<< (*i).first << ":"<<(*i).second << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后输出是

B:123
A:321
Run Code Online (Sandbox Code Playgroud)