10

我正在尝试使用这个 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;
}

有什么办法可以缩短这段代码?

每个新案例都具有相同的功能,直到前一个案例加上一个或两个新功能。

终极目标:目标是减少代码和代码中的手动输入。

请务必发布答案以减少代码长度。

到目前为止发布的所有答案都没有考虑自动创建数字本身,因为即使这些数字也有它们的模式。

4

4 回答 4

12

反转大小写并删除所有break. 然后删除 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
}
于 2013-10-03T06:51:16.250 回答
8

这里的一个选项是为 ; 创建一个包含四个可能选项的数组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. 的答案中的 fallthrough-switch 相比,此解决方案将使调用的调用顺序与function原始代码中的相同(这在function有副作用的情况下可能很重要,如评论中所述)。

params和的初始化paramMapping最好在实际计算函数之外完成(例如,在包含该函数的类的初始化中)。

结论:加上数字和参数之间的映射,这个实现实际上变得相当复杂,是否比原来的开关更简单还有待商榷。

于 2013-10-03T06:50:15.200 回答
3

如果你想在不增加运行时间的情况下减少代码重复量,你可以使用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
于 2013-10-03T08:33:51.493 回答
0

与@nyarlathotep 类似,我喜欢使用地图预先保存参数的方法。通过使用元组和 std::accumulate 可以使代码相当干净。不需要switch语句,只需要调用accumulate对所有函数求和即可。如果您想做除 sum 以外的事情,则易于操作,您可以使用 for_each 和您选择的函数。我在下面使用了 C++11,但认为这个想法适用于 C++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;
}
于 2013-10-03T16:09:51.850 回答