【问题标题】:sort an unordered_map using sort() [duplicate]使用 sort() 对 unordered_map 进行排序 [重复]
【发布时间】:2015-07-09 16:24:44
【问题描述】:

我正在尝试使用sort() 函数对unordered_map 进行排序,但我不断收到编译器错误。有人可以帮忙吗?

bool comp(pair<char,int> a, pair<char,int> b) {
    return a.second < b.second;
}

void rearrangeKDist(char str[], int d) {
    int n = strlen(str);
    unordered_map<char, int> table;
    for (int i=0; i<n; i++) {
        unordered_map<char, int>::iterator it = table.find(str[i]);   
        if (it == table.end()) {
            table.insert(make_pair(str[i], 1));
        } else {
            it->second = it->second+1;
        }
    }
    for (unordered_map<char, int>::iterator it=table.begin(); it!=table.end(); it++)
        cout<<it->first<<" "<<it->second<<endl;
    sort(table.begin(), table.end(), comp);
    for (unordered_map<char, int>::iterator it=table.begin(); it!=table.end(); it++)
        cout<<it->first<<" "<<it->second<<endl;

}

【问题讨论】:

  • 为什么要对无序地图进行排序?如果您需要对数据进行排序,请使用常规地图。 (PS:你不能就地排序。它会破坏地图的不变量)
  • 侧节点,而不是 find/insert/increment... 你可以这样做 ++table[str[i]];
  • 可能duplicate/我的解释here

标签: c++ unordered-map


【解决方案1】:

从编译和逻辑的角度来看,这是不可能的。从类型的角度来看,std::sort 需要:

-RandomIt必须满足ValueSwappable和RandomAccessIterator的要求。
-解引用的RandomIt的类型必须满足MoveAssignable和MoveConstructible的要求。

std::unordered_map 上的迭代器类型是 ForwardIterator,而不是 RandomAccessIterator,所以第一个要求不满足。解引用的迭代器的类型是pair&lt;const Key, T&gt;,不是MoveAssignable(不能赋值给const),所以第二个要求也不满足。

从逻辑的角度来看,对 无序 容器进行排序是没有意义的。它是无序的。并且unordered_map 能够实现的复杂性保证需要非常具体的顺序,您不应该也不允许弄乱。

如果您想“排序”您的unordered_map,请将它们放入vector

std::vector<std::pair<char, int>> elems(table.begin(), table.end());
std::sort(elems.begin(), elems.end(), comp);

【讨论】:

  • 对于std::sort,我们需要:#include &lt;algorithm&gt;
  • 您好,感谢您的回答,我真的很喜欢第一个原因的解释方式。我正处于从新手到中间人的过渡期,您能否就查看什么样的资源提出一些建议,以便我们可以像您在这里所做的那样以更扎实的方式解释问题?@Barry
猜你喜欢
  • 2021-05-29
  • 2023-03-28
  • 1970-01-01
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多