unordered_map 无法在工作 C++ 中初始化?

问题描述

问题:给定一个字符串 strs 数组,将字谜组合在一起。您可以按任意顺序返回答案。

字谜是通过重新排列不同单词或短语的字母而形成的单词或短语,通常只使用一次所有原始字母。

Example 1:

Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]

代码

class Solution
{
public:
    vector<vector<string>> groupAnagrams(vector<string> &strs)
    {
        unordered_map <unordered_multiset <char>,vector<string>> mp1;
        for (c : strs)
        {
            unordered_multiset<char> ms1;
            for (char h : c)
                m1.insert(h);
            mp1[ms1].push_back(c);
        }
        vector<vector<string>> res;
        for (auto c : mp1)
            res.push_back(c.second);
        return res;
    }
};

错误

Line 6: Char 67: error: call to implicitly-deleted default constructor of 'unordered_map<unordered_multiset<char>,vector<std::string>>' (aka 'unordered_map<unordered_multiset<char>,vector<basic_string<char>>>')
        unordered_map <unordered_multiset <char>,vector<string>> mp1;
                                                                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:141:7: note: explicitly defaulted function was implicitly deleted here
      unordered_map() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:105:18: note: default constructor of 'unordered_map<std::unordered_multiset<char,std::hash<char>,std::equal_to<char>,std::allocator<char>>,std::vector<std::__cxx11::basic_string<char>,std::allocator<std::__cxx11::basic_string<char>>>,std::hash<std::unordered_multiset<char,std::allocator<char>>>,std::equal_to<std::unordered_multiset<char,std::allocator<std::pair<const std::unordered_multiset<char,std::allocator<std::__cxx11::basic_string<char>>>>>>' is implicitly deleted because field '_M_h' has a deleted default constructor
      _Hashtable _M_h;
                 ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:414:7: note: explicitly defaulted function was implicitly deleted here
      _Hashtable() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:174:7: note: default constructor of '_Hashtable<std::unordered_multiset<char,std::pair<const std::unordered_multiset<char,std::allocator<std::__cxx11::basic_string<char>>>>,std::allocator<std::__cxx11::basic_string<char>>>>>,std::__detail::_Select1st,std::__detail::_Mod_range_hashing,std::__detail::_Default_ranged_hash,std::__detail::_Prime_rehash_policy,std::__detail::_Hashtable_traits<true,false,true>>' is implicitly deleted because base class '__detail::_Hashtable_base<unordered_multiset<char,hash<char>,equal_to<char>,allocator<char>>,pair<const unordered_multiset<char,vector<basic_string<char>,allocator<basic_string<char>>>>,_Select1st,equal_to<unordered_multiset<char,allocator<char>>>,hash<unordered_multiset<char,_Mod_range_hashing,_Default_ranged_hash,_Hashtable_traits<true,true>>' has a deleted default constructor
    : public __detail::_Hashtable_base<_Key,_Value,_ExtractKey,_Equal,^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1822:5: note: explicitly defaulted function was implicitly deleted here
    _Hashtable_base() = default;
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1771:5: note: default constructor of '_Hashtable_base<std::unordered_multiset<char,true>>' is implicitly deleted because base class '_Hash_code_base<std::unordered_multiset<char,true>::__hash_cached::value>' has a deleted default constructor
  : public _Hash_code_base<_Key,_H1,_H2,_Hash,^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1373:7: note: explicitly defaulted function was implicitly deleted here
      _Hash_code_base() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1349:7: note: default constructor of '_Hash_code_base<std::unordered_multiset<char,true>' is implicitly deleted because base class '_Hashtable_ebo_helper<1,std::allocator<char>>>>' has a deleted default constructor
      private _Hashtable_ebo_helper<1,_H1>,^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1096:7: note: explicitly defaulted function was implicitly deleted here
      _Hashtable_ebo_helper() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1094:7: note: default constructor of '_Hashtable_ebo_helper<1,true>' is implicitly deleted because base class 'std::hash<std::unordered_multiset<char,std::allocator<char>>>' has a deleted default constructor
    : private _Tp
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/functional_hash.h:101:19: note: default constructor of 'hash<std::unordered_multiset<char,std::allocator<char>>>' is implicitly deleted because base class '__hash_enum<std::unordered_multiset<char,std::allocator<char>>>' has no default constructor
    struct hash : __hash_enum<_Tp>
                  ^

解决方法

unordered_map 要求密钥类型有一个哈希函数。在这种情况下,它是 unordered_multiset <char>,但没有 std::hashunordered_multiset <char> 特化。您需要制作自己的哈希器才能使用它。

这里的错误信息不是最大的,但这就是暗指。

,

您不能按原样使用 unordered_multiset 作为 unordered_map 中的键,因为它没有 std::hash 特化。

您可以专门化 std::hash 或为 unordered_multiset 提供您自己的哈希函数。

但实际上这些都不是必需的,因为您可以使用已排序的 string 作为键:

vector<vector<string>> groupAnagrams(vector<string> &strs)
{
    map <string,vector<string>> mp1;
    for (auto &s : strs) {
        string sc = s;
        sort(begin(sc),end(sc));
        mp1[sc].push_back(s);
    }
    vector<vector<string>> res;
    for (auto &c : mp1) {
        res.push_back(c.second);
    }
    return res;
}
,

来自参考 here

你可能需要这样的东西

struct KeyHash {
        std::size_t operator()(const unordered_multiset <char>& k) const
        {
                // hashing logic
                return 0;
        }
};

struct KeyEqual {
 bool operator()(const unordered_multiset <char>& lhs,const unordered_multiset <char>& rhs) const
 {
        //Compare Logic
        return 0;
 }
};

然后

unordered_map <unordered_multiset <char>,vector<string>,KeyHash,KeyEqual> mp1;