3-key number with 2 keys

I have a structure containing 3 fields, two int (let them be called A and B ) and bool ( C ).

I want to create a kind of array of this structure and have access to it through any of the keys (A or B), getting a hole object (with A, B and C) in return. I don't need to do something like "getting the whole object for which bool is true" if that matters.

Obviously, both keys are unique, and the bool cannot be, but I thought I mentioned this for the sake of clarity.

If there weren’t A or B, it would be just std::map<int, bool> .

The only solution that I can see right now is to make a wrapper containing 2 set and vector . Is there a way to make my life easier?

NB: it will contain no more than one hundred tuples, so performance should not be a problem. Line access is acceptable.

To make this even clearer, here is what I would like to do:

 foobar<int, int, bool> array; // or something along those lines array.add(1, 101, true); array.add(2, 102, false); array.getA(1); // returns first object array.getA(2); // returns second object array.getB(102); // returns second object again 
+6
source share
4 answers

I believe you are looking for boost :: multi_index . This will allow you to declare a container with multiple indices.

 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; 

(Usable label namespace as suggested by Rapptz)

For example, you have a multi_index MultiIDStruct container for which there are two unique orderings: one on idA (which is a member of MultiIDStruct ), and the second on idB (which is also a member).

The template options at first seem small, but they are not so bad as soon as you understand how they work.

+6
source

The proposal to split it into two maps is, of course, a little easier, but if you want more flexibility and can use C ++ 11 for functions like std::tuple , you can try something like a form:

 #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 gives output 1, 102, 0 (false).

+1
source

I know that I have not implemented the details. But I just offer two-card logic. What is wrong with it? Why am I taking downvoted?

 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) { sp; pi=i; pj=j; pb=b; mapB[j]=p; mapA[i]=j; } 
0
source

Having the same problem and a different solution!

They have two hash functions on A and B, giving h1 (A) and h2 (B) such that they do not give equal values. Example:

 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; } 

Put all your stuff in std :: map so that hashA and hashB have the same value for bool. Access it with either hashA or hashB.

Example: A = 0x10000001, B = 0x20000002, C = true

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

card: 0x1000000100000000 β†’ true 0x0000000020000002 β†’ true

0
source

Source: https://habr.com/ru/post/948403/


All Articles