繁体   English   中英

unordered_map的正确值

[英]Proper value for unordered_map

我有一组字符串,我必须将其放入哈希表并检索它的字符串。 我选择了unordered_map,因为它是c ++中的内置哈希表。 字符串如下,

cat, act, art, tar, rat... etc..   

现在我使用按字母顺序排序的单词作为键,将无序单词的向量用作值。 这种实现在插入时花费了大量时间。 这是该要求的最佳实施方案,还是我可以使用的时间更少?

    std::tr1::unordered_map<std::string, std::vector<std::string>> map;
    if(map.find(sortedWord) == map.end()){
        std::vector<std::string> temp;
        temp.push_back(word);
        map.insert(make_pair(sortedWord, temp));
    }else{
        map.find(sortedWord)->second.push_back(word);
    } 

你所做的事情比必要的要复杂得多,而且在这个过程中你也会减慢速度:

  • 两次搜索密钥,和
  • 有新密钥时复制向量(包含单词)。 事实上,它可能被复制了两次。

以下适用于C ++ 11,我很确定它与tr1的工作方式相同:

/* Name of map changed because I don't like to use "map"
 * or "string" as variable names */
wordMap[sortedWord].push_back(word);

如果sortedWord不存在于地图上,然后wordMap[sortedWord]将与一个默认构造的插入它std::vector<std::string>> 因此,无论sortedWord是否存在,新单词都可以附加到下标返回的值上。

只是提供另一种解决方案,您可以使用C ++ 11 std::unordered_multiset和自定义散列算法以及相等比较。

自定义散列算法可以简单地将每个字符的散列值与换向操作(例如,bitwise-xor)组合,使得所有字符串具有相同的散列值。

自定义相等比较可以使用std::is_permutation来等同于所有字谜。

struct AnagramHash
{
    typedef std::string argument_type;
    typedef std::hash<char>::result_type result_type;

    result_type operator()(const argument_type& s) const
    {
        std::hash<char> char_hash;
        result_type result = 0;

        for (const auto& x : s)
        {
            result ^= char_hash(x);
        }

        return result;
    }
};

struct AnagramEqual
{
    typedef bool result_type;
    typedef std::string first_argument_type;
    typedef std::string second_argument_type;

    result_type operator()(const first_argument_type& lhs, const second_argument_type& rhs) const
    {
        if (lhs.size() == rhs.size())
            return std::is_permutation(std::begin(lhs), std::end(lhs), std::begin(rhs));
        else
            return false;
    }
};

int main()
{
    std::unordered_multiset<std::string, AnagramHash, AnagramEqual> anagrams;

    anagrams.insert("arc");
    anagrams.insert("rac");
    anagrams.insert("car");

    anagrams.insert("H2O");
    anagrams.insert("2OH");

    auto range = anagrams.equal_range("car");
    for (auto it = range.first ; it != range.second ; ++it)
    {
        cout << *it << endl;
    }

    cout << endl;

    range = anagrams.equal_range("HO2");
    for (auto it = range.first ; it != range.second ; ++it)
    {
        cout << *it << endl;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM