algorithm to find best match that may return none
I have some inputs that may be temporarily unavailable and that have an error associated.
struct sensorVal
{
bool available;
double error;
double va开发者_运维技巧l;
bool betterThan(const sensorVal* that) const;
}
I'm looking for an algorithm that will find the best available input. My best attempt so far is to use min_element
as follows:
bool sensorVal::betterThan(const sensorVal& that) const
{
if (available)
{
if (that.available)
return (error < that.error);
return true;
}
return false;
}
bool betterThan(const sensorVal& lhs, const sensorVal& rhs)
{
return lhs.betterThan(rhs);
}
std::vector<sensorVal>::const_iterator
find_best(const std::vector<sensorVal>& inputs)
{
std::vector<sensorVal>::const_iterator best;
best = min_element(inputs.begin(), inputs.end(), betterThan);
if (best->available)
return best;
return inputs.end();
}
This works fine except when all inputs are marked unavailable. In this case best is set to inputs.begin()
and I then need to test whether it is available.
I would prefer to have best set to inputs.end()
which is already catered for in my code.
Is there an existing algorithm that can find best match that can return that there are no suitable members? Or a way of rephrasing my test so that best is set to inputs.end()
.
thanks
Maybe you just want to make it look a little better?
best = min_element(inputs.begin(), inputs.end(), betterThan);
return best->available ? best : inputs.end();
You can use std::accumulate
instead, but I think the solution you already have is better.
struct best {
std::vector<sensorVal>::const_iterator end;
explicit best(std::vector<sensorVal>::const_iterator end) : end(end){}
std::vector<sensorVal>::const_iterator operator()(std::vector<sensorVal>::const_iterator l, std::vector<sensorVal>::const_iterator r) {
return (r->available() && (l == end() || r->error < l->error)) ? r : l
}
};
std::vector<sensorVal>::const_iterator
find_best(const std::vector<sensorVal>& inputs)
{
return std::accumulate(inputs.begin(), inputs.end(), inputs.end(), best(inputs.end());
}
Perhaps you can use std::partition() to sort the vector into available and unavailable inputs. Then use min_element to find the best within the available subset.
精彩评论