你如何处理离散的非整数数组?

时间:2008-12-07 23:23:30

标签: c floating-point d lookup

我有一个程序需要从一组已知的值到另一组已知值执行编译时可检查映射:

in      out
------------
8       37
10      61
12      92
13 1/4  109
15 1/4  151
etc

如果输入是整数或均匀间隔,这将很容易。我将迭代这些行,但也希望能够以可读的方式进行查找。

我当前的想法(我不喜欢)是定义类似

的枚举
enum Size
{
   _8,
   _10,
   _12,
   _13_25,
   _15_25,
   // etc
}

然后将其设置为2次查找。

有更好的想法吗?

编辑:我主要关心的是限制我可以尝试查找的内容。如果代码可能会尝试查找无效的内容,我希望甚至不编译

集合很小,迭代次数几乎完全不相关。

我还没有看到任何能让我获得任何东西的东西,所以现在我要去那里。 OTOH我会继续关注这个问题。

*注意:我并不担心使用指针捕获问题而不是,只需要像循环和变量赋值这样的直接代码。


细节:为了清晰和普遍,我简化了以上内容。我实际上有一个表有3个非整数,非均匀轴和一个非数字轴。在这一点上,我不确定我需要在哪个方向列举它。

一些链接,以了解我正在寻找的东西:

Boost::SI和我的D version theidea

6 个答案:

答案 0 :(得分:1)

你不能使用哈希映射吗?

答案 1 :(得分:1)

如果您的输入分数限制为某个2分之二分母,则可以使用定点数作为键。对于您的示例,使用1位= 0.25,(将每个输入乘以4),如下所示:

IN maps to Key
--         ---   
8          32   
10         40
12         48 
13 1/4     53
15 1/4     61 

KeyMin= 32

然后,您可以使用Key-KeyMin作为稀疏数组的索引,该数组包含无效条目的标志值,如-1。优点是,如果您的密钥发生变化,它将使您不必重新编码。缺点是浪费了记忆。

答案 2 :(得分:1)

使用枚举会丢失数值,除非您对变量名进行了丑陋的解析。我会这样做:

class Size
{
    public decimal Val{get;set;}
    private Size(decimal val){this.val = val;}
    public static Size _8 = new Size(8.0);   
    //...
    public Dictionary<Size, Size> sizeMap = new Dictionary<Size, Size>
    {
        {_8, _37}, 
        //...
    };
}

答案 3 :(得分:0)

听起来你想要使用像排序的二叉树这样的东西。查找和迭代都很快,树不关心条目的间距。

如果您的多个轴是独立的,您可以为每个轴创建一个。

答案 4 :(得分:0)

enum的想法并不太可怕,但我会动态地做。你有一个有效字符串的数组/列表。字符串列表中的索引是您映射的关键。

// this could be loaded from a file potentially
// notice that the keys have been sorted.
const char* keys[] = { "10", "12", "13 1/4", "15 1/4", "8", 0 };
float values[] = { 61, 92, 109, 151, 37, 0 };
int key_count = 0;
while (keys[key_count]) ++key_count;

bool find(const char* key, float* val) {
   int idx = bsearch(key, keys, sizeof(const char*), key_count, strcmp);
   if (idx < 0) return false;
   *val = values[idx];
   return true;
}

现在,你说了一些关于这里存在多个维度的内容。这只意味着你需要多个键阵列。

答案 5 :(得分:0)

以下是对如何解决问题的建议。使用结构和数组。

typedef struct{
    float input;
    int   output;
}m_lookup;
m_lookup in_out[] = 
{   
    (float) 8   , 37,
    (float)10   , 61,
    (float)12   , 92,
    (float)13.25,109,
    (float)15.25,151,
};

int get_Var(float input)
{
    int i=0;
    for(i=0;i<sizeof(in_out);i++)
        if(in_out[i].input == input)
            return in_out[i].output;
    // Here you could make some special code for your compiler
    return 0;
}
int main(void)
{
    printf("Input 15.25 : Output %d\n",get_Var(15.25));
    printf("Input 13,25 : Output %d\n",get_Var(13.25));
    printf("Illegal input:\n");
    printf("Input 5 : Output %d\n",get_Var(5));
    system( "pause" );
    return 0;
}

如果你再详细解释一下这种情况,我可能会做出一些调整。

如果你确定在编译时检查它,那么你可以使用这样的枚举:

enum Size
{
   i_8=37,
   i_10=61,
   i_12=92,
   i_13_25=109,
   i_15_25=151,
   // etc
}