2012-03-30 2 views
1

저는 맵에 0-300 = 10, 300-600 = 20, 600-900 = 30 ... 2500000-2700000 = 7000과 같은 값의 범위가 있습니다. switch-statement/if-block하지만이 작은 문제를 해결하기위한보다 우아한 접근 방법이 있는지 궁금합니다.대형 switch 문에 대해보다 세련된 솔루션이 있습니까?

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 
+0

O <= 300 = 10, 300 <600 = 20 그래서 300 = 10 – Pfitz

+0

그래서 모든를 300만큼 결과를 10 씩 늘리시겠습니까? 1150에 대한 결과는 무엇입니까? 그리고 '2500000 => 7000' 결과가 확실합니까? 패턴과 일치하지 않습니다. – sch

답변

5

switch 문을 제거하기위한 가장 일반적인 패턴은 사전을 사용하는 것입니다 : 여기에 좋아

은 실제 데이터가있는 테이블의 작은 하위 집합입니다. 귀하의 경우 범위를 매핑하므로 범위를 자르는 대신 NSArray을 사용하게됩니다. 실제로

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를로드 할 것 : 이것은 당신의 int를 처리하는 경우처럼 보일 것 인 것이다.

1

테이블을 사용할 수 있습니다. 예 : 다음

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 
}; 

그리고

단순히 대신 이진 검색을 사용할 수 있습니다, 그것은 정말 큰 테이블의 경우 권리 범위를

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; 
    } 
} 

을 찾아 그것을 통해 반복.

+0

OP 값이 10에서 7000으로 증가 할 것으로 예상됩니다 (어쩌면 그 이상). 'table'을 정의하기 위해 700 줄의 코드를 작성하는 것은 합리적이지 않습니다. – sch

+0

@sch : 그는 가능한 경우를 모두 알아들을 다른 방법은 없을까요? 그들은 어딘가에 입력해야합니다. – JeremyP

+0

내가 사용한 값은 단지 예일뿐입니다. 몇 가지 값이 될 것이지만 어쨌든 코드 /리스트를 통해 하드 코드해야합니다. – Pfitz

0

당신이 (C 예) 같은 것을 할 수있는 :

#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; 
} 

해야 출력 :

-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] 
관련 문제