当前位置:  开发笔记 > 编程语言 > 正文

如何优化多(矩阵)开关/案例算法?

如何解决《如何优化多(矩阵)开关/案例算法?》经验,为你挑选了2个好方法。

是否可以优化这种(矩阵)算法:

//        | case 1 | case 2 | case 3 |
//  ------|--------|--------|--------|
//        |        |        |        |
//  case a|   a1   |   a2   |   a3   |
//        |        |        |        |
//  case b|   b1   |   b2   |   b3   |
//        |        |        |        |
//  case c|   c1   |   c2   |   c3   |
//        |        |        |        |

switch (var)
    {
      case 1:
      switch (subvar)
      {
        case a:
          process a1;
        case b:
          process b1;    
        case c:
          process c1;
      }
      case 2:
      switch (subvar)
      {
        case a:
          process a2;
        case b:
          process b2;    
        case c:
          process c2;
      }
      case 3:
      switch (subvar)
      {
        case a:
          process a3;
        case b:
          process b3;    
        case c:
          process c3;
      }
    }

代码相当简单,但你必须想象更复杂的"开关/案例".

我使用3个变量.根据他们取值1,2,3或a,b,c或alpha,beta,charlie有不同的过程来实现.是否可以通过一系列"开关/外壳"来优化它?

(问题已经在法语中提到了这里).

编辑 :(来自Dran Dane对以下评论的回答.这些也可能在这个更显着的位置!)
" 优化 "应理解为必须编写更少的代码,更少的"切换/案例".我们的想法是提高可读性,可维护性,而不是性能.

可能有一种方法可以通过"责任链"编写更少的代码,但是这个解决方案在所有方面都不是最优的,因为它需要在内存中创建许多对象.



1> Robert Massa..:

听起来你想要的是一个'有限状态机',使用这些情况你可以激活不同的进程或'状态'.在C中,这通常使用函数指针的数组(矩阵)来完成.

所以你基本上创建一个数组并将正确的函数指针放在正确的标记上,然后使用'var'作为正确'process'的索引,然后你调用它.您可以在大多数语言中执行此操作.这样,机器的不同输入激活不同的过程并将其带到不同的状态.这对许多应用非常有用; 我自己一直在MCU开发中使用它.

编辑:Valya指出我可能应该展示一个基本模型:

stateMachine[var1][var2]();   // calls the right 'process' for input var1, var2


对不起,我会删除我的回答:)
非常感谢,你在这里看不到成熟,我希望我能为你+1.

2> mjv..:

这个问题没有好的答案:-(

因为这么多的回应取决于

有效目标("优化"是什么意思,嵌套交换机的不满意)

将要应用此构造的上下文(应用程序隐含的最终需求是什么)

TokenMacGuy明智地询问目标.我花时间检查问题及其在法国网站上的回复,我仍然对目标感到疑惑...... Dran Dane最近的回应似乎指向减少代码量/提高可读性但是让我们回顾一下:

处理速度:嵌套开关效率非常高,可能需要少于3次乘法才能获得映射表的索引,但可能不均匀.

可读性:是的可能是一个问题,随着变量和级别的增加,组合爆炸的数量增加,并且switch语句的格式也倾向于在长的垂直延伸上扩展分支点和相关值.在这种情况下,使用fct初始化3维(或更多)表.指针将分支值和要在单行上调用的函数放回原点.

写少量代码:对不起,这里帮助不大; 在一天结束时,我们需要考虑相对较多的组合,"地图",无论其形式如何,都必须写在某处.诸如TokenMacGuy之类的代码生成器可能会派上用场,在这种情况下看起来有点过分.发电机有它们的位置,但我不确定是这种情况.两种情况之一:如果变量和级别的数量足够小,那么生成器是不值得的(如果变量和级别的数量是变量,那么设置起来比创建实际代码要花费更多时间)重要的是,生成的代码难以阅读,难以维护...)

简而言之,我关于使代码更具可读性(并且编写速度更快)的建议是法国网站上描述的表/矩阵方法.

该解决方案分为两部分:
一次初始化三维阵列(3级); (或者如果愿意的话,可以使用"发烧友"的容器结构:例如树).这是通过以下代码完成的:

// This is positively more compact / readable
...
FctMap[1][4][0] = fctAlphaOne;
FctMap[1][4][1] = fctAlphaOne;
..
FctMap[3][0][0] = fctBravoCharlie4;
FctMap[3][0][1] = NULL;   // impossible case
FctMap[3][0][2] = fctBravoCharlie4;    // note how the same fct may serve in mult. places

在需要调用函数的地方有一个相对简单的代码片段:

if (FctMap[cond1][cond2][cond3]) {
  retVal = FctMap[cond1][cond2][cond3](Arg1, Arg2);
  if (retVal < 0)
      DoSomething(); // anyway we're leveraging the common api to these fct not the switch alternative ....
}

如果组合空间相对稀疏地填充(交换机"树"中的许多"分支"未被使用)或者某些功能需要不同的参数集,则可以提示使用上述解决方案的情况是:对于这两种情况,我想首先插入一个Joel Goodwin首先提出的解决方案,它基本上将几个级别的各种键组合成一个更长的键(如果需要,还有分隔符),基本上将问题归结为一个长但单级的开关语句.

现在...

真正的讨论应该是为什么我们首先需要这样的映射/决策树.不幸的是,要回答这个问题需要了解底层应用程序的真实性质.可以肯定的是,我并不是说这表明设计不好.在某些应用程序中,一个大的调度部分可能有意义.但是,即使使用C语言(法语站点贡献者似乎不符合面向对象的设计),也可以采用面向对象的方法和模式.无论如何,我正在分歧......)应用程序可能总体上更好地服务于替代设计模式,其中"关于什么时候调用的信息树"已经分布在几个模块和/或几个对象中.

抱歉以相当抽象的方式谈论这个问题,只是缺乏应用程序细节......重点仍然是:挑战我们需要这个大型调度树的想法; 想一想整个应用程序的替代方法.

Alors,bonne机会!;-)

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有