三张地图包括2把钥匙

时间:2013-06-30 00:43:14

标签: c++ map

我的结构包含3个字段,两个int s (让我们称之为 A B 和一个{ {1}} C

我想创建一个该结构的数组,并能够通过任何键(A或B)访问它,获得孔对象(带有A,B和C)作为回报。 我不需要做一些像“获取bool为真的所有对象”的内容,如果这有任何区别的话。

显然,这两个关键都是独一无二的,布尔不可以,但我想我是为了清楚起见而提到的。

如果没有A或B,那将是一个简单的bool

我目前看到的唯一解决方案是创建一个包含2 std::map<int, bool>set的包装器。 有什么方法可以让我的生活更轻松吗?

注意:它最多包含一百个元组,因此性能不应成为问题。线性访问是可以接受的。

为了使它更清晰,我希望能够做到这一点:

vector

4 个答案:

答案 0 :(得分:6)

我相信你所寻找的是boost::multi_index。它允许您声明具有多个索引的容器。

struct MultiIDStruct
{
    size_t idA;
    size_t idB;
    std::string name;
};

namespace mul = boost::multi_index;

boost::multi_index_container< MultiIDStruct, 
    mul::indexed_by< 
        mul::ordered_unique< mul::member< MultiIDStruct, size_t, &MultiIDStruct::idA > >,
        mul::ordered_unique< mul::member< MultiIDStruct, size_t, &MultiIDStruct::idB > > 
    > > data;

(根据Rapptz建议使用名称空间“快捷方式”)

例如,您有一个multi_index容器MultiIDStruct,其中有两个唯一的排序,一个在idAMultiIDStruct的成员)和一个第二个idB(也是会员)。

模板参数起初看起来很少,但一旦你理解了它们的工作方式,它们就不会那么糟糕了。

答案 1 :(得分:1)

将它拆分为两个映射的建议当然有点简单,但是如果你想要更多的灵活性并且可以将C ++ 11用于std::tuple等功能,你可以尝试以下形式:< / p>

#include <iostream>
#include <map>
#include <tuple>

template <typename T1, typename T2, typename T3>
class foobar
{
public:
    void add(T1 t1, T2 t2, T3 t3)
    {
        m1[t1] = std::make_tuple(t1, t2, t3);
        m2[t2] = std::make_tuple(t1, t2, t3);
    }

    std::tuple<T1,T2,T3> getA(T1 t1)
    {
        return m1[t1];
    }

    std::tuple<T1,T2,T3> getB(T2 t2)
    {
        return m2[t2];
    }

private:
    std::map<T1,std::tuple<T1,T2,T3>> m1;
    std::map<T2,std::tuple<T1,T2,T3>> m2;
};

int main()
{
    foobar<int, int, bool> array;  // or something along those lines

    array.add(1, 101, true);
    array.add(2, 102, false);

    auto res1 = array.getA(1); // returns first object
    auto res2 = array.getA(2);   // returns second object
    auto res3 = array.getB(102); // returns second object again

    std::cout << std::get<0>(res1) << std::endl;
    std::cout << std::get<1>(res2) << std::endl;
    std::cout << std::get<2>(res3) << std::endl;

    return 0;
}

A working example给出输出1,102,0(假)。

答案 2 :(得分:0)

我知道我没有详细说明。但我只是建议使用两张地图的逻辑。它出什么问题了?为什么我会被投票?

struct s
{
int i;
int j;
bool b;
};

std::map<int, int> mapA;
std::map<int, s> mapB;

const s& getA(int i)
{
    return mapB[mapA[i]];
}

const s& getB(int j)
{
    return mapB[j];
}

void add(int i, int j, bool b)
{
    s p;
    p.i=i;
    p.j=j;
    p.b=b;
    mapB[j]=p;
    mapA[i]=j;
}

答案 3 :(得分:0)

遇到同样的问题和不同的解决方案!

在A和B上有两个哈希函数,给出h1(A)和h2(B),它们不给出相等的值。例如:

uint32_t A;
uint32_t B;

uint64_t hashA(uint32_t value)
{ return ((uint64_t)value) << 32; }

uint64_t hashB(uint32_t value)
{ return (uint64_t)value; }

将所有内容放入std :: map,以便hashA和hashB具有相同的bool值。使用hashA或hashB访问它。

示例:A = 0x10000001,B = 0x20000002,C = true

hashA(A):0x1000000100000000 hashB(B):0x0000000020000002

图: 0x1000000100000000 - &gt;真正 0x0000000020000002 - &gt;真