在c ++中有一个用于哈希映射的复合键 [英] Having a composite key for hash map in c++

查看:189
本文介绍了在c ++中有一个用于哈希映射的复合键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据结构,包含

I have a data structure which has,

<Book title>, <Author>, and <rate>

由于Book标题或作者可以重复,我想构建一个复合键。
(假设我不能创建额外的唯一键,例如ID)

Since Book title or Author can be duplicated, I'd like to build a composite key. (let's say I cannot make extra unique key, such as ID)

由于数据相当巨大,我使用GCC unordered_map为速度,
和我建立我的结构像这样:

Since data is pretty huge, I'm using GCC unordered_map for the sake of speed, and I built my structure like this:

typedef pair<string, string> keys_t
typedef unordered_map<keys_t, double> map_t;

一般来说一切正常,
但是当我想引用一个特定的

Everything works okay in general, But the problem happens when I want to refer one specific key.

例如,假设我想在名为数学的书之中找到最好的书,或者我想找到平均值托尔斯泰的书的比率。

在这种情况下,这变得非常麻烦,因为我不仅可以只引用一个密钥对。

For example, let's suppose I'd like to find the best-rated book among books titled as "math", or I'd like to find the average rate of "Tolstoy"'s books.
In this case, this becomes very bothersome, since I cannot only refer only one of the key pair.

我碰巧找到 boost :: multi_index 但我有一些麻烦理解文档。

I happened to find boost::multi_index but I'm having some trouble understanding the documents. Does anyone have some idea or guideline for this?

多个索引的解决方案,multi_index的简洁示例,任何其他方法等。任何帮助将谢谢。

Solution to make multiple indices, succinct example for multi_index, any other approach, etc.. any help will be appreciated.

谢谢。

推荐答案

我想出了如何使用 boost :: multi_index
我引用这段代码:使用MEM_FUN启动multi_index复合键

这里是我的代码供您参考。

and here's my code for your reference.

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <string>

using namespace boost::multi_index;
using namespace std;

class Book {
public:
    Book(const string &lang1, const string &lang2, const double &value) : m_lang1(lang1) , m_lang2(lang2) , m_value(value) {}

    friend std::ostream& operator << (ostream& os,const Book& n)    {
        os << n.m_lang1 << " " << n.m_lang2 << " " << n.m_value << endl;
        return os;
    }

    const string &lang1() const { return m_lang1; }
    const string &lang2() const { return m_lang2; }
    const double &value() const { return m_value; }
private:
    string m_lang1, m_lang2;
    double m_value;
};

// These will be Tag names
struct lang1 {};
struct lang2 {};
struct value {};

typedef multi_index_container <
    Book, 
    indexed_by<
        ordered_non_unique<tag<lang1>, BOOST_MULTI_INDEX_CONST_MEM_FUN( Book, const string &, lang1)
        >,
        ordered_non_unique<tag<lang2>, BOOST_MULTI_INDEX_CONST_MEM_FUN(Book, const string &, lang2)
        >,
        ordered_non_unique<tag<value>, BOOST_MULTI_INDEX_CONST_MEM_FUN(Book, const double &, value), greater<double>
        >,
        ordered_unique<
            // make as a composite key with Title and Author
            composite_key<
                Book,
                BOOST_MULTI_INDEX_CONST_MEM_FUN(Book, const string &, lang1),
                BOOST_MULTI_INDEX_CONST_MEM_FUN(Book, const string &, lang2)
            >
        >
    >
> Book_set;

// Indices for iterators
typedef Book_set::index<lang1>::type Book_set_by_lang1;
typedef Book_set::index<lang2>::type Book_set_by_lang2;
typedef Book_set::index<value>::type Book_set_by_value;

int main() {

    Book_set books;
    books.insert(Book("Math", "shawn", 4.3));
    books.insert(Book("Math", "john", 4.2));
    books.insert(Book("Math2", "abel", 3.8));
    books.insert(Book("Novel1", "Tolstoy", 5.0));
    books.insert(Book("Novel1", "Tolstoy", 4.8)); // This will not be inserted(duplicated)
    books.insert(Book("Novel2", "Tolstoy", 4.2));
    books.insert(Book("Novel3", "Tolstoy", 4.4));
    books.insert(Book("Math", "abel", 2.5));
    books.insert(Book("Math2", "Tolstoy", 3.0));

    cout << "SORTED BY TITLE" << endl;
    for (Book_set_by_lang1::iterator itf = books.get<lang1>().begin(); itf != books.get<lang1>().end(); ++itf)
        cout << *itf;

    cout << endl<<"SORTED BY AUTHOR" << endl;
    for (Book_set_by_lang2::iterator itm = books.get<lang2>().begin(); itm != books.get<lang2>().end(); ++itm)
        cout << *itm;

    cout << endl<<"SORTED BY RATING" << endl;
    for (Book_set_by_value::iterator itl = books.get<value>().begin(); itl != books.get<value>().end(); ++itl)
        cout << *itl;

    // Want to see Tolstoy's books? (in descending order of rating)
    cout << endl;
    Book_set_by_lang2::iterator mitchells = books.get<lang2>().find("Tolstoy");
    while (mitchells->lang2() == "Tolstoy")
        cout << *mitchells++;

    return 0;
}

感谢所有发表评论的人!

Thank you all who made comments!

这篇关于在c ++中有一个用于哈希映射的复合键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆