user2725924
user2725924

Reputation: 159

To introduce loop inside c++ switch- case

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

Answers (4)

codeling
codeling

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

dwxw
dwxw

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

willj
willj

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

masoud
masoud

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

Related Questions