问题
I am trying to adapt a digital electronics problem to a C++ STL based program.
Originally I have 4 inputs C1, C2, C3, C4. This means I have a total of 16 combinations:
0000
0001
.
.
.
1111
I have a multimap defined by
typedef std::pair<int, int> au_pair; //vertices
typedef std::pair<int, int> acq_pair; //ch qlty
typedef std::multimap<int, acq_pair> au_map;
typedef au_map::iterator It_au;
The no. of simulations depend on the size of the au_map
.
For eg: if the au_map.size() = 5
I will have C1, C2, C3, C4, C5. and therefore 2^5 = 32 cases.
For example:
If theau_map.size()=4
, I need to simulate my algorithm for 16 cases.
for(It_au it = a_map.begin(); it != a_map.end(); it++)
{
acq_pair it1 = it->second;
//case 0:
//C3 = 0, C2 = 0, C1 = 0, C0 = 0
//Update it1.second with corresponding C values
//simulate algorithm
//case 1:
//C3 = 0, C2 = 0, C1 = 0, C0 = 1
//simulate
.........
//case 15:
//C3 = 1, C2 = 1, C1 = 1, C0 = 1
//simulate
}
回答1:
Not the best idea. Right now you're doing a lot of useless work by manually setting your C1-C4 and by writing some simulation routines right in your for
loop.
Automate it.
Use some abstract State-Simulator
mapper (where Simulator
actually stands for some concrete functional object).
typedef char State;
struct basic_simulator {
// You could also pass some other parameters to your
// simulator
virtual void operator()(...) = 0
};
struct concrete_simulator : public basic_simulator {
virtual void operator()(...) {
// Do something concrete
// Trolololo
}
};
typedef basic_simulator Simulator;
And in this case your actual wrapper would look like std::map<State, Simulator*> map;
What you need to do next do means getting C1-C4 values from your state which is defined as char
. Use bitwise operators.
All your states could be defined as 0-15
numbers converted to binary (2 -> 0010
). So to get C1-C4 values you would simply have to make appropriate shifts:
// C1 C2 C3 C4
// -----------
// 1 1 1 1
State state = 15;
for (int i = 3; i >= 0; i--) {
// State of some of the inputs, defined by one bit
InputState C_xx = ((state >> i) & 1);
}
Now simply map all those 0-15
states to appropriate simulating functor:
std::map<State, Simulator*> mapper;
// Generally speaking, you should use some sort of
// smart pointer here
mapper[0] = new concrete_simulator(...);
mapper[1] = ...
What is really cool that you could have only, let's say, 3 or four concrete simulators which would be mapped to some states accordingly.
In this case invoking actual simulation would mean something like:
// Fire appropriate simulation object
(*(mapper[actual_state]))(...);
and making every possible simulation means iterating over every map element.
Update: the same technique could be used for states where you have more than 4 inputs / single input state can have more than two possible values.
Just write an appropriate mapping function and state generator.
回答2:
Hum... why not letting a for
loop enumerate the various combinations for you ?
for (size_t i = 0; i != 16; ++i)
{
bool const c1 = i & 1;
bool const c2 = i & 2;
bool const c3 = i & 4;
bool const c4 = i & 8;
// your algorithm
}
A bit easier than setting them by hand.
来源:https://stackoverflow.com/questions/3110975/c-case-declaration