Reputation: 159
I am trying to use this switch - case statement. I was wondering if there is any other efficient way of writing this code. The "function" prototype is: int function(int a,int b, int c,int d)
switch (u) {
case 1:
t = t + function(0,2,1,0); // 1
break;
case 2:
t = t + function(0,2,1,0); // 1
t = t + function(1,2,2,0); // 2
break;
case 3:
t = t + function(0,2,1,0) ; // 1
t = t + function(1,2,2,0) ; // 2
t = t + function(0,3,3,1) ; // 3
break;
case 4:
t = t + function(0,2,1,0) ; // 1
t = t + function(1,2,2,0) ; // 2
t = t + function(0,3,3,1) ; // 3
t = t + function(1,3,4,1) ; // 4
t = t + function(3,2,4,0) ; // 6
break;
case 5:
t = t + function(0,2,1,0) ; // 1
t = t + function(1,2,2,0) ; // 2
t = t + function(0,3,3,1) ; // 3
t = t + function(1,3,4,1) ; // 4
t = t + function(2,3,5,1) ; // 5
t = t + function(3,2,4,0) ; // 6
t = t + function(4,2,5,0) ; // 7
break;
case 6:
t = t + function(0,2,1,0) ; // 1
t = t + function(1,2,2,0) ; // 2
t = t + function(0,3,3,1) ; // 3
t = t + function(1,3,4,1) ; // 4
t = t + function(2,3,5,1) ; // 5
t = t + function(3,2,4,0) ; // 6
t = t + function(4,2,5,0) ; // 7
t = t + function(3,3,6,1) ; // 8
break;
case 7:
t = t + function(0,2,1,0) ; // 1
t = t + function(1,2,2,0) ; // 2
t = t + function(0,3,3,1) ; // 3
t = t + function(1,3,4,1) ; // 4
t = t + function(2,3,5,1) ; // 5
t = t + function(3,2,4,0) ; // 6
t = t + function(4,2,5,0) ; // 7
t = t + function(3,3,6,1) ; // 8
t = t + function(4,3,7,1) ; // 9
t = t + function(6,2,7,0) ; // 11
break;
case 8:
t = t + function(0,2,1,0) ; // 1
t = t + function(1,2,2,0) ; // 2
t = t + function(0,3,3,1) ; // 3
t = t + function(1,3,4,1) ; // 4
t = t + function(2,3,5,1) ; // 5
t = t + function(3,2,4,0) ; // 6
t = t + function(4,2,5,0) ; // 7
t = t + function(3,3,6,1) ; // 8
t = t + function(4,3,7,1) ; // 9
t = t + function(5,3,8,1) ; // 10
t = t + function(6,2,7,0) ; // 11
t = t + function(7,2,8,0) ; // 12
break;
}
Is there any way to shorten this code?
Every new case has the same function till previous case plus one or two new function.
Ultimate Goal :The goal is to have less code and less manual entry inside the code.
Please do post an answer to decrease the length of code .
All the answers posted till now do not think about automagically creating the numbers themselves as even these numbers have a pattern with them.
Upvotes: 10
Views: 1109
Reputation: 11408
One option here would be to create an array of the four possible options to the function
; and a mapping of which of these parameters to use for any value of u
.
Then you can do those calls with the mapped parameters in a loop.
Like this:
int params[12][4] = {
{0,2,1,0}, // 1
{1,2,2,0}, // 2
{0,3,3,1}, // 3
// ...
};
vector<vector<int> > paramMapping;
paramMapping.push_back({1});
paramMapping.push_back({{1, 2});
paramMapping.push_back({{1, 2, 3});
paramMapping.push_back({{1, 2, 3, 4, 6});
paramMapping.push_back({{1, 2, 3, 4, 5, 6, 7});
// ..
vector<int>::iterator it = paramMapping[u-1].begin();
while (it != paramMapping[u-1].end())
{
int i = (*it) - 1;
t += function(params[i][0], params[i][1], params[i][2], params[i][3]);
++it;
}
This solution, in contrast to the fallthrough-switch in M M.'s answer, would keep the calling order of the function
calls the same as in your original code (which could be important in case function
has side-effects, as mentioned in the comments).
The initialisation of the params
and paramMapping
should best be done outside of the actual computing function (somewhere in the initialisation of the class that contains the function for example).
Conclusion: With the addition of the mapping between number and parameters, this implementation has actually become quite complex, and its debatable whether its simpler than the original switch.
Upvotes: 8
Reputation: 1099
Similar to @nyarlathotep, I like the approach of using a map to hold the parameters beforehand. By using a tuple and std::accumulate you can make the code fairly clean. No need for the switch statement, just call accumulate to sum up all the functions. Easy to manipulate if you want to do something other than sum, you could use a for_each and a function of your choice. I've used C++11 below, but think the idea would work with C++03 and TR1.
#include <iostream>
#include <map>
#include <list>
#include <tuple>
#include <numeric>
using namespace std;
int function(int a, int b, int c, int d)
{
return 1;
}
typedef tuple<int,int,int,int> ParamType;
int addfunc(int a, ParamType b)
{
return a + function(get<0>(b),get<1>(b),get<2>(b),get<3>(b));
}
int main() {
map<int, list<ParamType>> params;
params[1] = {make_tuple(0,2,1,0)};
params[2] = {make_tuple(0,2,1,0), make_tuple(1,2,2,0)};
// and so on...
// later on when you want to use it
int u = 1;
int t = 0;
t = accumulate(params[u].begin(), params[u].end(), t, addfunc);
return 0;
}
Upvotes: 0
Reputation: 2999
If you want to reduce the amount of code duplication without increasing the time it takes to run, you can use if
instead of switch
:
assert(u < 9);
if(u >= 1) t = t + function(0,2,1,0) ; // 1
if(u >= 2) t = t + function(1,2,2,0) ; // 2
if(u >= 3) t = t + function(0,3,3,1) ; // 3
if(u >= 4) t = t + function(1,3,4,1) ; // 4
if(u >= 5) t = t + function(2,3,5,1) ; // 5
if(u >= 4) t = t + function(3,2,4,0) ; // 6
if(u >= 5) t = t + function(4,2,5,0) ; // 7
if(u >= 6) t = t + function(3,3,6,1) ; // 8
if(u >= 7) t = t + function(4,3,7,1) ; // 9
if(u >= 8) t = t + function(5,3,8,1) ; // 10
if(u >= 7) t = t + function(6,2,7,0) ; // 11
if(u >= 8) t = t + function(7,2,8,0) ; // 12
Upvotes: 3
Reputation: 56509
Reverse the cases and remove all break
. Then remove common +=
:
switch (u)
{
case 8:
t += function(5, 3, 8, 1); // 11
t += function(7, 2, 8, 0); // 12
case 7:
t += function(4, 3, 7, 1); // 9
t += function(6, 2, 7, 0); // 10
case 6:
t += function(4, 2, 5, 0); // 7
t += function(3, 3, 6, 1); // 8
case 5:
t += function(2, 3, 5, 1); // 5
t += function(4, 2, 5, 0); // 6
case 4:
t += function(1, 3, 4, 1); // 4
t += function(3, 2, 4, 0); // 5
case 3:
t += function(0, 3, 3, 1); // 3
case 2:
t += function(1, 2, 2, 0); // 2
case 1:
t += function(0, 2, 1, 0); // 1
}
Upvotes: 12