更有效的检查范围的方法?

时间:2017-05-09 18:54:03

标签: c

给定index(0-3)和输入Region,我必须确定哪个index Config 0,所以输出为1,2,3 ,或4。

注意:值的范围由某个公式确定,例如,让我们忽略Config 1-3并查看range,假设0-111被定义为数字2*7*{0-7}+{0-13}和它来自公式2*7*8+range(最后两个数字来自我们现在可以忽略的其他参数),对于后续区域,它分别是4*7*8+range6*7*8+rangeindex因此这些价值观。

现在,我要检查配置,然后执行范围检查,检查+--------------+---------+---------+---------+---------+ |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

我的逻辑是:

function sendBytesToSpeech (bytes, encoding, rate, callback) {
  gapi.client.speech.speech.syncrecognize({
    config: {
      encoding: encoding,
      sampleRate: rate
    },
    audio: {
      content: bytes
    }
  }).execute(function (r) {
    callback(r);
  });
}

function sendBlobToSpeech (blob, encoding, rate) {
  var speechSender = new FileReader();
  speechSender.addEventListener('loadend', function () {
    sendBytesToSpeech(btoa(speechSender.result), encoding, rate, uiCallback);
  });
  speechSender.readAsBinaryString(blob);
}

有没有更好的方法来执行此代码而不仅仅是做一堆if-elses?我觉得可以确定配方中的其他参数,但我似乎无法看到它。

3 个答案:

答案 0 :(得分: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;

};

答案 1 :(得分: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;
    }
}

答案 2 :(得分:1)

commentedselbie应该可以为结构使用初始值设定项。反击是:

  

我试过了。我不断得到一个&#34;太多的初始化器&#34;错误...

这里证明了它是可能的,但它比我预期的更令人兴奋,在初始化器中需要5个(如在&#39; 5&#39;!)级别的大括号​​。

struct Table table =
{   // structure
    {   // array
        {   // structure
            {   // array
                { "1st",   0,  56 },
            },
        },
        {   {   { "1st",   0, 111 },   },   },
        …
    },
};

这比我预期的要复杂得多。它使数据布局变得痛苦。我不确定我是否在上方或下方都有一个非常好的布局。

这里是完整的代码(主要基于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 |
+---------------+---------+---------+---------+---------+