hash_map / unordered_map中的项目顺序是否稳定?

时间:2012-11-29 09:16:12

标签: c++ stl hashmap unordered-map

当hash_map / unordered_map加载了相同的项时,它们会在迭代时具有相同的顺序吗?基本上我有一个hashmap,我从一个文件加载,并从中定期将有限数量的项目提供给一个例程,之后我释放hashmap。在使用这些项目之后,我将相同的文件重新加载到hashmap,并希望在我停止上一次之后获取下一批项目。我停止的点将由钥匙识别。

2 个答案:

答案 0 :(得分:2)

技术上不,他们不能保证按任何特定顺序。

然而,在实践中,鉴于您使用确定性散列函数,您想要做的应该没问题。

考虑

std::string name;
std::string value;

std::unordered_map <std::string, std::string> map1;
std::unordered_map <std::string, std::string> map2;

while (read_pair (name, value))
{
    map1[name] = value;
    map2[name] = value;
}

您可以合理地预期map1map2中的名称 - 值对的顺序相同。

答案 1 :(得分:2)

不,你不能安全地做到这一点。首先,它不是标准所保证的,但即使你忽略标准并看实际实现,这也是一个坏主意。

大多数哈希表结构不是历史记录。也就是说:哈希表的状态不仅取决于它包含的项目,还取决于它们插入的 order

这是一个具体的例子:

#include <unordered_map>
#include <string>
#include <iostream>

static const char* const NAMES[] = {
    "joe",
    "bob",
    "alexander",
    "warren",
    "paul",
    "michael",
    "george",
    "david",
    "peter"
};
static const int NAME_COUNT = sizeof(NAMES)/sizeof(NAMES[0]);

static void print_umap(const std::unordered_map<std::string, int>& m) {
    for (const auto& item : m) {
        std::cout << "  " << item.first << "\n";
    }
}

int main(void) {
    std::unordered_map<std::string, int> a;
    std::unordered_map<std::string, int> b;
    std::unordered_map<std::string, int> c;

    for (int i = 0; i < NAME_COUNT; ++i) {
        a[NAMES[i]] = 0;
        b[NAMES[NAME_COUNT - 1 - i]] = 0;
    }

    for (const auto& item : a) {
        c[item.first] = 0;
    }

    std::cout << "a:\n";
    print_umap(a);
    std::cout << "\n\nb:\n";
    print_umap(b);
    std::cout << "\n\nc:\n";
    print_umap(c);
    return 0;
}

当我使用clang和C ++标准库的libc++实现构建它时,我得到以下输出:

a:
  peter
  george
  michael
  david
  paul
  bob
  warren
  alexander
  joe


b:
  joe
  alexander
  bob
  warren
  david
  paul
  michael
  george
  peter


c:
  joe
  alexander
  warren
  bob
  paul
  david
  michael
  george
  peter

请注意,订单在每种情况下都不同。这对哈希表来说并不罕见。