首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于大型switch语句,有没有更优雅的解决方案?

对于大型switch语句,有没有更优雅的解决方案?
EN

Stack Overflow用户
提问于 2012-03-30 17:15:57
回答 3查看 692关注 0票数 1

我已经将许多范围映射到一个值,如0-300 = 10,300-600 = 20,600-900 = 30 ... 2500000-2700000 =7000...所以我可以做一个非常大的switch-statement/ if -block,但是我想知道是否有更优雅的方法来解决这个小问题。

好的,下面是包含真实数据的表格的一小部分:

代码语言:javascript
复制
0-300 : 25
301-600.  : 45
601-900 : 65
901-1200. : 85
1201-1500: 105

1501-2000 : 133
2001-2500 : 161
2501-3000: 189
3001-3500:217
3501-4000:245

4001-4500:273
4501-5000:301
5001-6000:338
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-30 17:24:45

摆脱switch语句的最常见模式是使用字典。在本例中,由于您映射的是范围,因此将使用范围截止的NSArray。如果你在处理int,它看起来就像这样:

代码语言:javascript
复制
NSArray *rangeCutoffs = [NSArray arrayWithObjects:[NSNumber numberWithInt:300],[NSNumberWithInt:600],...,nil];
NSArray *values = [NSArray arrayWithObjects:[NSNumber numberWithInt:10], [NSNumber numberWithInt:20],...,nil];

int mappedInt;
for (int index=0; index <= [rangeCutoffs count]; index++) {
    if (intToMap < [[rangeCutoffs objectAtIndex:index] intValue]) {
        mappedInt = [[values objectAtIndex:index] intValue];
    }
}
if (mappedInt == 0) {
    mappedInt = [[values lastObject] intValue];
}

实际上,您可能希望从plist加载rangeCutoffsvalues,而不是对它们进行硬编码。

票数 5
EN

Stack Overflow用户

发布于 2012-03-30 17:34:08

你可以用一张桌子。例如:

代码语言:javascript
复制
struct Lookup
{
    int min;
    int max;
    int value;
};

struct Lookup table[] =
{
    {       0,     300,   10 },
    {     301,     600,   20 },
    {     601,     900,   30 },
    // other ranges
    { 2500000, 2700000, 7000 },
    { -1, -1, -1 } // marks the end of the table
};

然后简单地遍历它以找到正确的范围

代码语言:javascript
复制
int result = -1;
for (int i = 0 ; table[i].min != -1 && result == -1 ; ++i)
{
     if (table[i].min <= value && value <= table[i].max)
     {
         result = table[i].value;
     }
}

如果这是一个非常大的表,您可以使用二进制搜索来代替。

票数 1
EN

Stack Overflow用户

发布于 2012-03-30 17:39:40

您可以这样做(C示例):

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

typedef int range_type;
typedef int value_type;

typedef struct {
    range_type min;
    range_type max;
    value_type value;
} range_t;

const range_t *find_range(const range_t *ranges, size_t rangesSize,
    value_type valueToFind)
{
    for (size_t i = 0; i < rangesSize; ++i) {
        if (ranges[i].min <= valueToFind && valueToFind <= ranges[i].max)
            return &ranges[i];
    }
    return NULL;
}

int main() {
    const range_t ranges[] = {
        {   0,  300, 10 },
        { 301,  600, 20 },
        { 601,  900, 30 },
        { 901, 1200, 40 }
        // And so on...
    };

    value_type testValues[] = {
          -1,                   // None
           0, 299,  300,    // [  0,  300]
         301, 599,  600,    // [301,  600]
         601, 899,  900,    // [601,  900]
         901, 1199, 1200,   // [901, 1200]
         // And so on...
    };

    for (size_t i = 0; i < sizeof(testValues) / sizeof(testValues[0]); ++i) {
        const range_t *match = find_range(
            ranges, sizeof(ranges) / sizeof(ranges[0]), testValues[i]);
        if (match != NULL)
            printf("%d found at [%d..%d]\n", testValues[i], match->min,
                match->max);
        else
            printf("%d not found\n", testValues[i]);
    }
    return EXIT_SUCCESS;
}

应输出:

代码语言:javascript
复制
-1 not found
0 found at [0..300]
299 found at [0..300]
300 found at [0..300]
301 found at [301..600]
599 found at [301..600]
600 found at [301..600]
601 found at [601..900]
899 found at [601..900]
900 found at [601..900]
901 found at [901..1200]
1199 found at [901..1200]
1200 found at [901..1200]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9940150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档