Bob Davis
December 2nd, 2004, 06:40 AM
This is a somewhat simple problem, but I'm looking for an elegant solution using the STL. Let's say that I have some STL container containing std::pair<unsigned char, float> objects. I want some function that will take a float as an argument and return the unsigned char associated with the float that is closest to the input argument in absolute value. For instance:
/* Assume pairList contains:
(1, 0.5)
(2, 1.0)
(3, 2.0)
(4, 4.0)
*/
unsigned char charValue = findClosestValue(pairList.begin(), pairList.end(), 2.5);
// For this call, charValue would now equal 3.
What I've thought of doing now is using std::min_element to find the "minimum" value in the list; I would then provide a predicate structure that would compare its two arguments against the input float value (in the above example, 2.5), like this:
whateverContainerTypeIUse<unsigned char, float>::iterator it = std::min_element(pairList.begin(), pairList.end(), AbsoluteValueDifferenceCompare(2.5));
What I'm hoping to avoid would be the linear search through the list of pairs that std::min_element would have to do. The list will be sorted ascendingly according to the floating point portion of the pair, so I was hoping to be able to leverage some sort of binary search algorithm to improve performance.
To anyone who is interested in what this is for: this would be written for an embedded system that contains a DAC. The DAC is controlled by writing a byte to an internal register; this changes the output voltage. However, the function mapping the voltage to the register value is nonlinear, so it is best to just use a lookup table to find the "best" register value for a particular voltage. I just want the user to be able to pass a specific voltage level to this function, and it will do the best it can to set the DAC to that level.
I would welcome any suggestions. Thanks!
/* Assume pairList contains:
(1, 0.5)
(2, 1.0)
(3, 2.0)
(4, 4.0)
*/
unsigned char charValue = findClosestValue(pairList.begin(), pairList.end(), 2.5);
// For this call, charValue would now equal 3.
What I've thought of doing now is using std::min_element to find the "minimum" value in the list; I would then provide a predicate structure that would compare its two arguments against the input float value (in the above example, 2.5), like this:
whateverContainerTypeIUse<unsigned char, float>::iterator it = std::min_element(pairList.begin(), pairList.end(), AbsoluteValueDifferenceCompare(2.5));
What I'm hoping to avoid would be the linear search through the list of pairs that std::min_element would have to do. The list will be sorted ascendingly according to the floating point portion of the pair, so I was hoping to be able to leverage some sort of binary search algorithm to improve performance.
To anyone who is interested in what this is for: this would be written for an embedded system that contains a DAC. The DAC is controlled by writing a byte to an internal register; this changes the output voltage. However, the function mapping the voltage to the register value is nonlinear, so it is best to just use a lookup table to find the "best" register value for a particular voltage. I just want the user to be able to pass a specific voltage level to this function, and it will do the best it can to set the DAC to that level.
I would welcome any suggestions. Thanks!