Представить цикл внутри С++ switch-case

Я пытаюсь использовать этот оператор switch-case. Мне было интересно, есть ли другой эффективный способ написания этого кода. Прототипом "функции" является: 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;
}

Есть ли способ сократить этот код?

Каждый новый случай имеет ту же функцию до предыдущего случая плюс одна или две новые функции.

Конечная цель: цель состоит в том, чтобы иметь меньше кода и меньше ручного ввода внутри кода.

Пожалуйста, напишите ответ, чтобы уменьшить длину кода.

Все ответы, опубликованные до сих пор, не думают о автоматическом создании самих чисел, так как даже эти цифры имеют с ними образец.

Ответ 1

Если вы хотите уменьшить количество дублирования кода, не увеличивая время, затрачиваемое на выполнение, вы можете использовать if вместо 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

Ответ 2

Отмените случаи и удалите все break. Затем удалите общий +=:

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
}

Ответ 3

Один из вариантов здесь - создать массив из четырех возможных вариантов function; и отображение какого из этих параметров использовать для любого значения u.

Затем вы можете выполнять эти вызовы с отображенными параметрами в цикле.

Вот так:

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

Это решение, в отличие от ответного переключателя в ответе M M., будет поддерживать порядок вызовов function так же, как и в вашем исходном коде (что может быть важно в случае, если function эффекты, как указано в комментариях).

Инициализация params и paramMapping лучше всего делать за пределами фактической вычислительной функции (где-то в инициализации класса, который содержит функцию, например).

Заключение: С добавлением сопоставления между числом и параметрами эта реализация фактически стала довольно сложной, и ее дискуссионный вопрос был ли проще, чем исходный.

Ответ 4

Подобно @nyarlathotep, мне нравится подход к использованию карты для предварительного хранения параметров. Используя кортеж и std:: accumulate, вы можете сделать код довольно чистым. Нет необходимости в инструкции switch, просто звоните, чтобы суммировать все функции. Легко манипулировать, если вы хотите сделать что-то другое, кроме суммы, вы можете использовать for_each и функцию по вашему выбору. Я использовал С++ 11 ниже, но думаю, что идея будет работать с С++ 03 и 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;
}