Brad
Brad

Reputation: 10670

Mapping combination of 4 integers to a single value

I have 4 separate integers that need to be mapped to an arbitrary, constant value.

For example, 4,2,1,1 will map to the number 42

And the number 4,2,1,2 will map to the number 86.

Is there anyway I can achieve this by using #define's or some sort of std::map. The concept seems very simple but for some reason I can't think of a good, efficient method of doing it. The methods I have tried are not working so I'm looking for some guidence on implementation of this.

Upvotes: 0

Views: 343

Answers (4)

Michael Anderson
Michael Anderson

Reputation: 73490

Will a simple function suffice?

int get_magic_number( int a, int b , int c, int d)
{
   if( (a==4)&&(b==2)&&(c==1)&&(d==1) ) return 42;
   if( (a==4)&&(b==2)&&(c==1)&&(d==2) ) return 86;
   ...
   throw SomeKindOfError();
}

Now that may look ugly, but you can easily create a macro to pretty it up. (Or a helper class or whatever... I'll just show the macro as I think its easy.

int get_magic_number( int a, int b , int c, int d)
{
   #DEFINE MAGIC(A,B,C,D,X) if((a==(A))&&(b==(B))&&(c==(C))&&(d==(D))) return (X);
   MAGIC(4,2,1,1,  42);
   MAGIC(4,2,1,2,  86);
   ...
   #UNDEF MAGIC
   throw SomeKindOfError();
}

If you really care you can probably craft a constexpr version of this too, which you'll never be able to do with std::map based solutions.

Upvotes: 2

juanchopanza
juanchopanza

Reputation: 227418

If you do not have access to boost::tuple, std::tuple or std::array, you can implement a type holding 4 integers with a suitable less-than comparison satisfying strict weak ordering:

struct FourInts {
  int a,b,c,d;
  FourInts() : a(), b(), c(), d() {}
  bool operator<(const FourInts& rhs) const {
    // implement less-than comparison here
  }
};

then use an std::map:

std::map<FourInts, int> m;

If you organise your ints in an array of standard library container, you can use std::lexicographical_compare for the less-than comparison.

Upvotes: 1

Yuushi
Yuushi

Reputation: 26040

Utilize a std::map<std::vector<int>, int>, so that the vector containing {4,2,1,1} will have the value 42, and so on.

Edit: I agree std::tuple would be a better way to go if you have a compiler with C++11 support. I used a std::vector because it is arguably more portable at this stage. You could also use a std::array<int, 4>.

Upvotes: 2

Alexander Chertov
Alexander Chertov

Reputation: 2108

If you know there's always 4 integers mapped to 1 integer I suggest you go with:

std::map< boost::tuple<int, int, int, int>, int >

Comparison (lexicographical) is already defined for tuples.

Upvotes: 0

Related Questions