用C / C ++声明这些表的干净方法?

时间:2013-05-30 08:59:46

标签: c++ c

我需要在我的C ++程序中使用静态表来查找组合。

这是一个简单的例子(我的表格会大3-4倍):

int TABLE[3][3] = {
           /*2*/ /*4*/ /*8*/ 
    /*2*/   {4,    8,    16},
    /*4*/   {8,    16,   32},
    /*8*/   {16,   32,   64}
};

我喜欢这种表,因为从索引中查找组合非常容易,而且很容易看到组合。

但是我不喜欢'键'只在注释中定义,这似乎是错误的。

是否有人在代码中定义了类似的表格,是否有任何一般性建议?

编辑:无法计算我的表格。它是特定于程序的“设置”。

4 个答案:

答案 0 :(得分:3)

由于您标记了您的问题,因此您可以始终在另一个std::unordered_map内使用std::unordered_map

std::unordered_map<int, std::unordered_map<int, int>> TABLE = {
    { 2, { { 2,  4 }, { 4,  8 }, { 8, 16 } } },
    { 4, { { 2,  8 }, { 4, 16 }, { 8, 32 } } },
    { 8, { { 2, 16 }, { 4, 32 }, { 8, 64 } } }
//    ^      ^   ^
//    |      |   |
//    |      |   value at [row][column]
//    |      |
//    |      column
//    row
};

// ...

std::cout << TABLE[1][5] << '\n';  // Outputs `0`
std::cout << TABLE[4][6] << '\n';  // Outputs `0`
std::cout << TABLE[4][4] << '\n';  // Outputs `16`

在普通C中,如果没有填充数组,就无法在特定的“键”处使用特定值:

int TABLE[9][9] = {
    {  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0,  4,  0,  8,  0,  0,  0, 16 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0,  8,  0, 16,  0,  0,  0, 32 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0, 16,  0, 32,  0,  0,  0, 64 }
};

但是你应该注意不要超越索引,因为你将索引越界。

答案 1 :(得分:3)

如果您需要恒定的查找时间,并且不想使用unordered_map(例如,因为您可以轻松地避免哈希计算),您可以将编码与查找分开。

  1. 将数据编码为友好的类型和读取结构,包括元数据:

    struct TableElement {
        int row;
        int col;
        int val;
    } raw_table[] = {
        {2, 2,  4}, {2, 4,  8}, {2, 8, 16},
        {4, 2,  8}, {4, 4, 16}, {4, 8, 32},
        {8, 2, 16}, {8, 4, 32}, {8, 8, 64} };
    

    (你可以通过一些工作来创造更美丽的东西)

  2. 从此初始化快速查找(一次,在启动时)。这可能是:

    • 没有索引计算的稀疏数组,如Joachim的答案的后半部分,
    • 密集阵列以获得更好的缓存行为
    • 或甚至具有自定义哈希函数的unordered_map

答案 2 :(得分:1)

来自C ++ 11:

#include <vector>

int main()
{
  using std::vector;
  vector<vector<int>> table = {
       /*2*/ /*4*/ /*8*/ 
       /*2*/   {4,    8,    16},
       /*4*/   {8,    16,   32},
       /*8*/   {16,   32,   64} };
}

对于std::array,这将解决问题:

#include <array>

int main()
{
  using std::array;
  array<array<int,3>,3> table = {{
       /*2*/ /*4*/ /*8*/ 
       /*2*/   {4,    8,    16},
       /*4*/   {8,    16,   32},
       /*8*/   {16,   32,   64} }};
}

还要考虑不使用多维数组,而是使用带索引技巧的一维数组。

答案 3 :(得分:1)

如果你只是讨厌这些评论,最简单的方法绝对是宏。

#define _(x)

int TABLE[3][3] = {
          _(2)  _(4)  _(8) 
    _(2)   {4,    8,    16},
    _(4)   {8,    16,   32},
    _(8)   {16,   32,   64}
};

^ _ ^