【问题标题】:using a switch statement to see which 'bin' a number falls into使用 switch 语句查看数字属于哪个“bin”
【发布时间】:2010-06-04 04:17:56
【问题描述】:

假设我有一堆垃圾箱,每个垃圾箱都包含一系列数字。一个例子是:

bin 1: 0-8
bin 2: 9-16
bin 3: 17-24
etc

有没有办法使用 switch 语句来确定数字属于哪个 bin?我试图弄清楚如何让案例反映一个数字在一个范围内,但它们似乎不是“常量表达式”,所以我不确定这是否可能..

编辑

我可能应该更准确;我的垃圾箱是 2 的幂...

bin 1: 0 to 2^3
bin 2: 2^3 + 1 to 2^4
bin 3: 2^4 + 1 to 2^5
etc

【问题讨论】:

    标签: c switch-statement


    【解决方案1】:

    您不能在 C 中为 case 标签使用范围 - 只能使用单个(常量表达式)值。

    如果范围很小,就像你的例子,那么你可以这样做:

    switch (value)
    {
        case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
        bin = 1;
        break;
    
        case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16:
        bin = 2;
        break;
    
        case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24:
        bin = 3;
        break;
    
        default:
    }
    

    或者,您可以使用查找表:

    static const int val_bin[] = {
        1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 to 8 */
        2, 2, 2, 2, 2, 2, 2, 2, /* 9 to 16 */
        3, 3, 3, 3, 3, 3, 3, 3 /* 17 to 24 */
    };
    
    bin = val_bin[value];
    

    或者,在某些情况下,您可以确定一个简单的公式。您当前的示例似乎是这样的情况:

    bin = 1 + (value - 1 / 8);
    

    对编辑的回应:

    对于您更新的问题,2 的幂,这实际上很容易。您可以使用“位涂抹”技术将位于两个二次幂之间的所有值转换为一个值(假设您使用unsigned long 表示value,最大值为2^32 - 1):

    if (value > 0)
        value -= 1; /* This is needed because your specified bins are "off by one" from the natural definitions */
    
    value |= value >> 16;
    value |= value >> 8;
    value |= value >> 4;
    value |= value >> 2;
    value |= value >> 1;
    
    switch (value)
    {
        case 0x00000000UL: /* 0, 1 */
        case 0x00000001UL: /* 2 */
        case 0x00000003UL: /* 2^1 + 1 ... 2^2 */
        case 0x00000007UL: /* 2^2 + 1 ... 2^3 */
        bin = 1;
        break;
    
        case 0x0000000fUL: /* 2^3 + 1 ... 2^4 */
        bin = 2;
        break;
    
        case 0x0000001fUL: /* 2^4 + 1 ... 2^5 */
        bin = 3;
        break;
    
        /* etc */
    }
    

    【讨论】:

      【解决方案2】:

      你可以级联它们:

      案例0:案例1:案例2:案例3:案例4:.....案例8: 做点什么(); 休息; 案例 9:案例 10:....... 等等

      【讨论】:

        【解决方案3】:

        如果您的编译器是 GCC,那么您很幸运。 GCC 有一个名为 case ranges 的扩展,它允许您像这样编写开关:

        switch (value) {
            case 0 ... 8:
                bin = 1;
                break;
            case 9 ... 16:
                bin = 2;
                break;
            /* and so on */
        }
        

        这不是标准的 C!

        【讨论】:

          猜你喜欢
          • 2012-02-14
          • 2013-02-03
          • 2021-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多