2017-05-09 10 views
0

Config(0-3)を考えると入力index、Iはであるため、出力は1,2,3、または4範囲を確認するより効率的な方法は?値の範囲は、によって決定される:

注あるRegionindexかを決定しなければなりませんたとえば、Config 0を無視してConfig 1-3を見てみましょう。rangeが数字0-111と定義されており、それが式2*7*{0-7}+{0-13}から来ているとしましょう(最後の2つの数値は現在無視できる追加パラメータに由来します)。 2*7*8+range,4*7*8+range,6*7*8+rangeであり、これらの値である。

ここで設定を確認してから、indexが特定の領域の最小値と最大値の間にあることを確認する範囲チェックを実行します。その場合は、この表を与えられた:

+--------------+---------+---------+---------+---------+ 
|Region\Config | 0 | 1 | 2 | 3 | 
+--------------+---------+---------+---------+---------+ 
|  1st  | 0-56 | 0-111 | 0-111 | 0-111 | 
+--------------+---------+---------+---------+---------+ 
|  2nd  |   |   | 112-223 | 112-223 | 
+--------------+---------+---------+---------+---------+ 
|  3rd  |   |   |   | 224-335 | 
+--------------+---------+---------+---------+---------+ 
|  4th  |   |   |   | 336-447 | 
+--------------+---------+---------+---------+---------+ 

私のロジックは次のとおりです。

- If config 0, <if index is 0-56> return 1 
- If config 1, <if index is 0-111> return 1 
- If config 2, if index is between 0-111, return 1 
       else if between 112-223, return 2 
- If config 3, if index is between 0-111, return 1 
       else if between 112-223, return 2 
       else if between 224-335, return 3 
       else if between 336-447, return 4 
- Bottom of function: return -1 

は、このコードを実行するだけではなく、もし、よその束を行うための良い方法はありますか?私は数式の追加パラメータを確認することが可能だと思うが、私はそれを見ることができない。

+1

2次元アレイ。 – sturcotte06

+1

2次元配列のアイデアを列のバイナリ検索と組み合わせる。 – selbie

+1

configが0でインデックス値が57以上(または負)の場合、問題が発生しています。あなたの疑似コードはそれを認識していないようです。 configが3でインデックス値が448以上の場合は、問題があります。あなたは何をすべきかを決める必要があります。いくつかの種類の2D配列(構造の?)が分かりやすいかもしれません。無効な構成番号とインデックス番号をどのように認識して報告するかを知っているだけです。また、テーブルの最後の行の335は336であるべきです。 –

答えて

2

2次元配列を使用できますが、各領域、設定、および表全体を表す入れ子構造のセットを使用することをお勧めします。

#define MAX_REGIONS 4 
#define MAX_CONFIGS 4 

struct Region { 
    char* name; 
    int min; 
    int max; 
}; 

struct Config { 
    struct Region regions[MAX_REGIONS]; 
}; 

struct Table { 
    struct Config configs[MAX_CONFIGS]; 
}; 

そして、与えられた設定と検索インデックスための領域を見つけるためにテーブルを検索する:

int searchTable(struct Table* table, int configIndex, int value) { 
    if ((configIndex < 0) || (configIndex >= MAX_CONFIGS)) { 
     return -1; // out of range 
    } 

    struct Config* config = &table->configs[configIndex]; 
    for (int x = 0; x < MAX_REGIONS; x++) { 
     struct Region* region = &config->regions[x]; 
     if ((value >= region->min) && (value <= region->max)) { 
      return x; 
     } 
    } 
    return -1; // not found 
} 

そして、最初にテーブルを構築するために、あなたはこのようなコードを持っているでしょう

int main() 
{ 
    struct Table table; 
    table.configs[0].regions[0].name = "1st"; 
    table.configs[0].regions[0].min = 0; 
    table.configs[0].regions[0].max = 56; 
    // ... 
    table.configs[3].regions[3].name = "4th"; 
    table.configs[3].regions[3].max = 335; 
    table.configs[3].regions[3].max = 447; 

}; 
+0

実行可能コードの束の代わりにイニシャライザを使用することができます。確かに、中括弧に注意する必要がありますが、それは大きな問題ではありません。 –

+0

私は試しました。中括弧で値のネストされたセットを実行しようとすると、「あまりにも多くのイニシャライザ」エラーが発生し続けます。私が動作させる唯一の方法は 'Config'と' Table'を 'typedef Region Config [4]'と 'typedef Config Table [4]'として宣言することでした。しかし、私はそれを行うときにメンバー変数を失います。 (Visual Studioではネストされた構造体が好きではないか、何か間違っていることがあります)。お気軽に何か提案してください。 – selbie

+0

私の[回答](http://stackoverflow.com/a/43885632/)を参照してください。私はそれがイニシャライザで5つのレベルのブレースを必要とすることに気づいたことに驚きました!しかし、私が見るものはVisual Studioでもうまくいくはずです。 –

1

存在する特定の境界値は一貫したパターンに従うので、式で領域番号を計算できます。どのような場合でも、配列に集計された構成ごとの制限と比較することで、入力が範囲外であるかどうかを確認できます。例えば、

int get_region(unsigned char config, unsigned int index) { 
    static const unsigned int upper_bound[] = { 56, 111, 223, 447}; 
    static const size_t num_configs = sizeof(upper_bound)/sizeof(upper_bound[0]); 

    if (config >= num_configs || index > upper_bound[config]) { 
     // handle input error; maybe: 
     return -1; 
    } else { 
     return (index/112) + 1; 
    } 
} 
1

構造のための初期化子を使用することが可能でなければなりませんselbieにI commented。リプロステは

でした。私はここではそれが可能であることの証明だが、5を必要とする、より心吹き、私は予想以上だった

...「あまりにも多くの初期化子」エラーを取得しておく(「5」のように!)中括弧のレベル初期化子。

予想よりも複雑でした。これは、データのレイアウトを苦痛にさせる。私は上か下かに本当に良いレイアウトがあるかどうかは分かりません。

ここでは、質問内のテーブルをシミュレートするためにテーブルを印刷してデータが機能することを確認する完全なコード(ほとんどがselbieのコードに基づいています)です。検索機能はstatic inlineとなっており、コンパイラ(GCC 7.1.0)は使用されていないと不平を言わないようにしています。

#include <stdio.h> 

#define MAX_REGIONS 4 
#define MAX_CONFIGS 4 

struct Region { 
    char* name; 
    int min; 
    int max; 
}; 

struct Config { 
    struct Region regions[MAX_REGIONS]; 
}; 

struct Table { 
    struct Config configs[MAX_CONFIGS]; 
}; 

static inline int searchTable(struct Table* table, int configIndex, int value) { 
    if ((configIndex < 0) || (configIndex >= MAX_CONFIGS)) { 
     return -1; // out of range 
    } 

    struct Config* config = &table->configs[configIndex]; 
    for (int x = 0; x < MAX_REGIONS; x++) { 
     struct Region* region = &config->regions[x]; 
     if ((value >= region->min) && (value <= region->max)) { 
      return x; 
     } 
    } 
    return -1; // not found 
} 

static void print_line(int wid_1, int wid_2, int num_2) 
{ 
    putchar('+'); 
    for (int i = 0; i < wid_1; i++) 
     putchar('-'); 
    for (int k = 0; k < num_2; k++) 
    { 
     putchar('+'); 
     for (int i = 0; i < wid_2; i++) 
      putchar('-'); 
    } 
    putchar('+'); 
    putchar('\n'); 
} 

int main(void) 
{ 
    struct Table table = 
    { 
     { 
      { { { "1st", 0, 56 }, }, }, 
      { { { "1st", 0, 111 }, }, }, 
      { { { "1st", 0, 111 }, 
       { "2nd", 112, 223 }, }, }, 
      { { { "1st", 0, 111 }, 
       { "2nd", 112, 223 }, 
       { "3rd", 224, 335 }, 
       { "4th", 336, 447 }, }, }, 
     }, 
    }; 

    print_line(15, 9, MAX_CONFIGS); 
    printf("| %-13s ", "Region/Config"); 
    for (int i = 0; i < MAX_CONFIGS; i++) 
     printf("| %d ", i); 
    puts("|"); 
    print_line(15, 9, MAX_CONFIGS); 
    for (int i = 0; i < MAX_REGIONS; i++) 
    { 
     printf("|  %s  ", table.configs[MAX_CONFIGS-1].regions[i].name); 
     for (int j = 0; j < MAX_CONFIGS; j++) 
     { 
      if (table.configs[j].regions[i].name == NULL) 
       printf("|   "); 
      else 
       printf("| %3d-%-3d ", table.configs[j].regions[i].min, 
            table.configs[j].regions[i].max); 
     } 
     puts("|"); 
     print_line(15, 9, MAX_CONFIGS); 
    } 

    return 0; 
} 

出力:

+---------------+---------+---------+---------+---------+ 
| Region/Config | 0 | 1 | 2 | 3 | 
+---------------+---------+---------+---------+---------+ 
|  1st  | 0-56 | 0-111 | 0-111 | 0-111 | 
+---------------+---------+---------+---------+---------+ 
|  2nd  |   |   | 112-223 | 112-223 | 
+---------------+---------+---------+---------+---------+ 
|  3rd  |   |   |   | 224-335 | 
+---------------+---------+---------+---------+---------+ 
|  4th  |   |   |   | 336-447 | 
+---------------+---------+---------+---------+---------+ 
+0

それを愛する!これを見せてくれてありがとう。 – selbie

関連する問題