switch-case结构是否实现为二进制搜索?

时间:2014-10-20 16:17:44

标签: compiler-construction switch-statement

我想知道如何实施switch - case声明:

示例

说一个人有以下代码:

Scanner sc = new Scanner(System.in);
int v = sc.nextInt();
switch(v) {
    case 0 :
        System.out.println("Zero");
        break;
    case 1 :
        System.out.println("One");
        break;
    case 2 :
        System.out.println("Two");
        break;
    //...
    default :
        System.out.println("No one digit number");
}

可以将其实现为:

if(v == 0) {
    System.out.println("Zero");
}
else if(v == 1) {
    System.out.println("One");
}
else if(v == 2) {
    System.out.println("Two");
}
//...
else {
    System.out.println("No one digit number");
}

但更有效的计划是:

if(v >= 0 && v <= 9) {
    if(v <= 5) {
        if(v <= 2) {
            if(v <= 1) {
                if(v == 0) {
                    System.out.println("Zero");
                }
                else {
                    System.out.println("One");
                }
            else {
                System.out.println("Two");
            }
        }
        //...
    }
    //...
}
else {
    System.out.println("No one digit number");
}

这很重要,因为有些程序(比如编译器编译器)编写Java / C#/ C ++源代码,从而生成非常大的switch语句。

2 个答案:

答案 0 :(得分:5)

Switch / case语句使用二元决策树和跳转表的组合实现,具体取决于案例范围。

  1. 对于简单的switch语句(2-3种情况),发出简单的if语句通常更有效,具体取决于值的密集程度(例如1 2 3 vs 1 2 9)。

  2. 对于具有单个密集组的较大基数交换机,通常直接或间接使用基于测试值的跳转表。

  3. 使用稀疏组或密集和稀疏组的混合,二进制决策树用于对组列表进行二等分,并在组内使用跳转表(树的叶子)。

  4. 所以答案是肯定的,有时候,但不是那么简单。

    可以填写&#34;空&#34;具有默认跳转的案例槽,以允许构建密集范围。对于小分支或针对非整数值的分支,切换被重写为条件(例如允许切换字符串或正则表达式的语言)。在您的示例中,数字0-9的情况肯定会被编码为查找表,因为它是一个密集组。

    在所有情况下,二元决策树是发出有效的开关/案例结构的重要部分。

    .NET CLR甚至有一个接受跳转表的操作码,它隐藏了默认情况的处理,这允许运行时在没有全流分析的情况下验证代码是否安全。

答案 1 :(得分:3)

切换语句的实现方式取决于&#39;案例&#39;名单。当一套&#39;案例&#39;密集,可以使用跳转表(如goto Label[v]语句,如果存在)。这比二分搜索要快得多。