2012-03-22 62 views
3

虽然与NLP打我已经遇到了一点小问题:嵌套开关替代

switch(var1) 
{ 
case Variant1_1: 
    if(cond1) 
    { 
     if(cond2) 
     { 
      if(cond3) 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
      else // cond3 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
     } 
     else // cond2 
     { 
      if(cond3) 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
      else // cond3 
      { 
       switch(var2) 
       { 
       case Variant2_1: 
        return someExpression; 
       // another five-six cases 
       default: 
        return; 
       } 
      } 
     } 
    } 
    else // cond1 
    { 
     // same thing 

    } 
    break; 
case Variant1_2: 
    // same gigantic tree 
    break; 
case Variant1_3: 
    // here too 
    break; 
default: 
    return; 
} 

是这样的“计算树”有什么办法?唯一出现在我脑海中的是一些带有函数指针叶子和很多小函数的树形容器。

+0

这段代码应该重构,不仅在这个函数中,而且还有其他函数。有时候,重构只有一个函数没有多大帮助,或者并不那么容易,但是考虑整个项目的设计(或者至少其他相关函数)会有很大帮助。然后,重构很容易,您可以期望更好的整体设计。 – Nawaz 2012-03-22 15:31:12

+0

对于每个条件组合,表达式是否真的独立?在我的经验中很少见。通常情况下,可以考虑一些共同点来减少个案的尝试次数。 – 2012-03-22 15:31:33

+0

考虑到这是NLP ..我想还会有更多的:-) – MadRunner 2012-03-22 15:55:38

回答

4

(在面颊上的舌头)每当您在C++程序中遇到switch声明时,您都知道您错过了继承机会。我知道重构多个并行开关的两种方式是(1)构建函数指针的多维数组,以及(2)使用visitor pattern的变体。

+0

O'kay,我想我会停下来多阵列,谢谢! 但是,对于没有经验的程序员,您能否在这种情况下澄清您对“访客模式”使用的看法? – MadRunner 2012-03-22 16:03:57

0

你所描述的是编译器会从你的代码中得到什么:)所以你基本上提出了一个嵌套的编程语言,它带来了格林斯潘的定律:“任何足够复杂的C或Fortran程序都包含一个广告特别的,非正式的,错误的,慢一半的Common Lisp。“

有些方法可以更好地编写此代码来表达您的条件。当你有很多嵌套的if() { if() { if() } } }时,通常只需编写if (!condition) break;或其他转义方法,简化代码。并不总是,但很多时候。

1

一个很好的解决方法是使用矩阵。

这将很好地工作,如果你知道所有的条件无论如何都会被评估。

制作一个多维阵列,将所述真 - 假值映射到处理功能。

Arrayswitch[var1][cond1][cond2][cond3][var2](); 
1

我开始寻找一种数据驱动的方法,当代码开始看起来像这样。它可以像表格一样简单,也可以像您建议的那样使用带有函数指针的树。

如果这是某种类型的手动解析器,您可能需要查看一些关于解析的参考资料,以了解如何使用语法定义进行解析(通过解释需求语法或使用使用语法作为输入的代码生成工具)。

我经常用手卷的递归下降解析器。通常,我创建一个保存状态的类,公开一个“Parse”函数,并将每个规则实现为一个私有成员函数。这些成员函数很小且明确命名,所以代码变得很可读。为它编写测试也很容易。

+0

这不仅仅是这种情况,这个函数处理flex,但感谢您的想法!猜猜我会尽快使用它:-) – MadRunner 2012-03-22 16:15:09