I have a big table which inclues values according to parameters like x and y. How can i find a values fast enough without high cpu load?
if fairly small, a straight table lookup might be in order. which inclues values how many/how large values per lookup?
to clarify here is a "sample answer" x can be 0-14; y can be 1-22; every pair of x and y must fetch 2 chars and an int
Erik
As noted, you can have a two-dimensional table where every allowed x value (with an optional offset) is represented in one dimension, and every allowed y value (with an optional offset) is represented in another value.
Then you can do:
if (x within range && y within range) { return table_lookup[x - X_OFFSET][y - Y_OFFSET]; }
If x and y are sparse, i.e. they span a huge number range but most (x,y) pairs are not represented, then you will have to settle for a binary search.
Use a one-dimensional vector such as:
struct { int x,y; int result; } array[] = { {...}, {...}, };
Make sure that all entries are sorted on first x and within the same x values on the y index.
Then do a binary search. Look at the middle entry. If x is too high, or x matches but y is too high, then select the middle entry from the first half of the array. If x is too small or x matches but y is too small, select the middle entry from the last half of the array.
Repeat until you have found a match, or subdivided the array enough times that there are zero entries left to try. Every extra subdivision will support a twice-as-large table so you can process a huge table with very few subdivisions. 20 subdivisions can handle 2^20 entries, or more than a million entries...
I haven't looked into the RTL of the C51 compiler, but look for a function called bsearch(). If it doesn't exist, or is too slow because of the function-pointer argument, then you can google for the actual implementation and modify the source to fit your needs.
And you can of course create a hash table, to get constant-time lookup of sparse data, but most hash implementations wastes quite a lot of memory so it can be a problematic algorithm for small embedded processors.
To give you more information my table is like this :
X Z Y X1 V1 V2 X2 V2 V2 . . . . . . . . . Xn Vn Vn
There are 192 rows for that table. Z and Y are selected manualy. I should get V value in every 1 second, according to intersection of X and Z (or Y, if selected) values i get from program automaticaly.
The only extra information you added was that you had 192 entries.
Still no information about the full range of the x and z variables and if the table is sparse or if every single x value for the full range of x values has an entry for every single z value.
I can write 192 as 16x12, so I could guess that that x can take the value 0..15 and y can take the value 0..11. Then you can use a two-dimensional array and perform a direct lookup.
But if the number of allowed values for x times the number of allowed values for z is more than 192, then you can't. And in that situation, you haven't specified if you just want to know if there is a match in the table, or if you want to find the closest match if an exact match isn't possible.
every X has Y and Z match. So let say i search v value for X3 according to Y i will find V3 the exact match.
I rather hope that's not really so, because it makes no sense at all. If all your "Z" and "Y" values are the same, what's the point of having two of them?
As-is, you don't seem to have Y as a function of X and Z, or Z as a function of X and Y, like you said you did. You have X and V as a function of an index number that goes from 1 to n.
OK here is:
1) You select y or z from menu of your program.This will be manual selection. 2) You are getting x values from a sensor to cpu 3) You are matching this x value with y or z according to your first sellection in step 1
For example :
x y z 1 11 23 2 10 22 3 9 26 4 7 20 . . . . . . 192 34 24
1) I selected y so i will use y values for my next matching operations. 2) I got x value (lets say 4) from a sensor automaticaly 3) then i should match x and y for 4. So result will be 7.
The problem is values are not mathematical they are random so i could not write formulas. I need matching form table as fast as i can.
That is a one-dimensional lookup, and it seems like all x values between 1 and 192 are represented. So instant lookup...
struct { unsigned y,z; } my_table[] = { {11,23}, {10,22}, ... }; my_y_result = my_table[x-1].y; my_z_result = my_table[x-1].z;
You may optionally define y = 0 and z = 1 and have a two-dimensional array:
unsigned my_array[][2] = { {11,23}, {10,22}, ... }; my_y_result = my_table[x-1][0]; my_z_result = my_table[x-1][1];