Bas*_*mme 5 algorithm matrix switch-statement
是否可以优化这种(矩阵)算法:
// | 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;
}
}
Run Code Online (Sandbox Code Playgroud)
代码相当简单,但你必须想象更复杂的"开关/案例".
我使用3个变量.根据他们取值1,2,3或a,b,c或alpha,beta,charlie有不同的过程来实现.是否可以通过一系列"开关/外壳"来优化它?
(问题已经在法语中提到了这里).
编辑 :(来自Dran Dane对以下评论的回答.这些也可能在这个更显着的位置!)
" 优化 "应理解为必须编写更少的代码,更少的"切换/案例".我们的想法是提高可读性,可维护性,而不是性能.
可能有一种方法可以通过"责任链"编写更少的代码,但是这个解决方案在所有方面都不是最优的,因为它需要在内存中创建许多对象.
Rob*_*oli 13
听起来你想要的是一个'有限状态机',使用这些情况你可以激活不同的进程或'状态'.在C中,这通常使用函数指针的数组(矩阵)来完成.
所以你基本上创建一个数组并将正确的函数指针放在正确的标记上,然后使用'var'作为正确'process'的索引,然后你调用它.您可以在大多数语言中执行此操作.这样,机器的不同输入激活不同的过程并将其带到不同的状态.这对许多应用非常有用; 我自己一直在MCU开发中使用它.
编辑:Valya指出我可能应该展示一个基本模型:
stateMachine[var1][var2](); // calls the right 'process' for input var1, var2
Run Code Online (Sandbox Code Playgroud)
因为这么多的回应取决于
TokenMacGuy明智地询问目标.我花时间检查问题及其在法国网站上的回复,我仍然对目标感到疑惑...... Dran Dane最近的回应似乎指向减少代码量/提高可读性但是让我们回顾一下:
简而言之,我关于使代码更具可读性(并且编写速度更快)的建议是法国网站上描述的表/矩阵方法.
该解决方案分为两部分:
一次初始化三维阵列(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
Run Code Online (Sandbox Code Playgroud)
在需要调用函数的地方有一个相对简单的代码片段:
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 ....
}
Run Code Online (Sandbox Code Playgroud)
如果组合空间相对稀疏地填充(交换机"树"中的许多"分支"未被使用)或者某些功能需要不同的参数集,则可以提示不使用上述解决方案的情况是:对于这两种情况,我想首先插入一个Joel Goodwin首先提出的解决方案,它基本上将几个级别的各种键组合成一个更长的键(如果需要,还有分隔符),基本上将问题归结为一个长但单级的开关语句.
真正的讨论应该是为什么我们首先需要这样的映射/决策树.不幸的是,要回答这个问题需要了解底层应用程序的真实性质.可以肯定的是,我并不是说这表明设计不好.在某些应用程序中,一个大的调度部分可能有意义.但是,即使使用C语言(法语站点贡献者似乎不符合面向对象的设计),也可以采用面向对象的方法和模式.无论如何,我正在分歧......)应用程序可能总体上更好地服务于替代设计模式,其中"关于什么时候调用的信息树"已经分布在几个模块和/或几个对象中.
抱歉以相当抽象的方式谈论这个问题,只是缺乏应用程序细节......重点仍然是:挑战我们需要这个大型调度树的想法; 想一想整个应用程序的替代方法.
Alors,bonne机会!;-)
来自developpez.com的解决方案 是的,您可以优化它并使其更加干净。您不能对工厂使用这样的“责任链”:
public class ProcessFactory {
private ArrayList<Process> processses = null;
public ProcessFactory(){
super();
processses = new ArrayList<Process>();
processses.add(new ProcessC1());
processses.add(new ProcessC2());
processses.add(new ProcessC3());
processses.add(new ProcessC4());
processses.add(new ProcessC5(6));
processses.add(new ProcessC5(22));
}
public Process getProcess(int var, int subvar){
for(Process process : processses){
if(process.canDo(var, subvar)){
return process;
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,就像您的进程使用 canXXX 实现接口进程一样,您可以轻松使用:
new ProcessFactory().getProcess(var,subvar).launch();
Run Code Online (Sandbox Code Playgroud)