How do you feel about discrete sets of non-integers?

I have a program that needs to execute a map to compile time from one known set of values ​​to another known set of values:

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

This would be easy if the inputs were either whole or evenly spaced. I will be iterating through the lines, but I also want to be able to search a readable manor.

My current thought (I don't like) is to define an enum like

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

      

and then set it up for two searches.

Any better ideas?

Edit: My main concern is to limit what I can try to find. I'd like the stuff to not even compile in case the code might try to find something invalid.

The set is small and the iteration time is almost irrelevant.

I haven't seen anything that could bring me anything about listing, so for now I'll go with that. OTOH I'll follow up on this.

*

Note. I'm not worried about pointer issues and what not, just straight forward code like for loops and variable assignments.


Cruel sadness : I've simplified above for clarity and generality. Actually I have a table with three non-integer, non-uniform axes and one non-numeric axis. And at this point I'm not sure which directions I need to list.

a few links to give a taste of what I'm looking for:

Boost :: SI and my D version of the same idea

+1


source to share


6 answers


Can't you use a hash map?



+1


source


If your input fractions are limited to some power-2 denominator, you can use the fixed point numbers as keys. For your example, use 1 bit = 0.25 (multiply each input by 4) like this:

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

KeyMin= 32

      



Then you can use Key-KeyMin as an index in the sparse array that contains the -1 flag value for invalid entries. The advantage is that it saves you the trouble of re-encoding if your keys change. The disadvantage is memory loss.

+1


source


By using enums, you lose a numeric value unless you do ugly parsing on the variable name. I would do this:

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}, 
        //...
    };
}

      

+1


source


It sounds like you want to use something like a sorted binary tree. Both search and iteration are fast, and the tree does not care about the distance of records.

If your multiple axes are independent, you can create one for each axis.

0


source


The enum idea wasn't too terrible, but I would do it dynamically. You have an array / list of valid strings. An index to a list of strings is your key to your map.

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

      

Now you said something about there being more than one dimension. This means you need multiple key arrays.

0


source


Here is a suggestion on how you might have solved it. Using structures and arrays.

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

      

Perhaps I could make some adjustments if you explain a little more about The nitty grity.

If you have defined a compile-time check for it, you can use an enum like this:

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

      

0


source







All Articles