Карта - найти ближайшее значение? - PullRequest
1 голос
/ 18 июля 2011

Я пытаюсь найти ближайшее значение RGB в QMap (я знаю, что это, вероятно, HSV, но это не проблема). Вот что я получил до сих пор:

        it = images_map.find(current_rgb);

        if(it != images_map.begin()){
            mi = images_map.lowerBound(current_rgb).value();
        }
        else{
            mi = images_map.upperBound(current_rgb).value();
        }

Моя карта выглядит так, что имеет следующие индексы:

images_map[ 4283914078 ] 
images_map[ 4284046165 ] 
images_map[ 4284902241 ] 
images_map[ 4289239953 ] 
images_map[ 4282200377 ] 
images_map[ 4289440688 ] 

Когда мой current_rgb, например, 4285046165, это нормально, но если какое-то значение больше, чем наибольший индекс, программа вылетает. Что я делаю не так?

Ответы [ 3 ]

3 голосов
/ 18 июля 2011

Возможно, потому что .value() пытается отменить ссылку на несуществующий элемент?

Это похоже на вашу собственную реализацию карты (или обертку), но ваша логика кажется неверной

  1. Вы звоните lowerBound каждый раз - кроме случаев, когда искомый предмет является первым на карте
  2. Если он первый на карте, вы снова выполняете поиск ???
  3. Если вы не выполняете поиск снова (который, если он уже найден, повторяет операцию снова), в противном случае, если не найден, ищет ближайший (что нормально), однако вы обрабатываете случай, когда его нет (т.е. *)

Логика должна выглядеть примерно так:

it = images_map.find(current_rgb);

if(it == images_map.end())
{
  it = images_map.lowerBound(current_rgb);
  if (it == images_map.begin())
  {
    it = images_map.upperBound(current_rgb);
    if (it == images_map.end()) 
      // throw error
  }
  // now you know you have a valid iterator - de-reference
  mi = *it.value();
}
1 голос
/ 18 июля 2011

Звоните

images_map.upperBound(current_rgb) 

Может вернуть

images_map.end()

В этом случае вам не следует звонить value().

0 голосов
/ 18 июля 2011

Вы можете решить проблему итератора вне диапазона, добавив дозорные значения 0x000000 и 0xFFFFFF (один раз). Таким образом, у вас всегда будет действительный нижний и верхний предел. Конечно, это может повлиять на результат вашего алгоритма. Например. если ваш «самый маленький» реальный цвет был чисто-синим (0x0000FF), то темно-синий (0x00007F) теперь найдет черный, а не чистый синий. Конечно, это легко исправить двумя сравнениями.

С дозорными на месте, звоните QMap::lower_bound. Вам нужно проверить, действительно ли вы нашли точное совпадение: если *lower_bound - это то значение, которое вы хотите, верните его. Иначе, lower_bound указывает на первый элемент, который больше, чем ваш ввод. Следовательно, --lowerbound указывает на последний элемент, который меньше вашего ввода. Проверьте, какой из двух ближе.

Обратите внимание, что единственный способ lower_bound может указывать на begin - это когда ваш ввод точно равен 0x000000 (часовой), и в этом случае вы не получите --lower_bound. Там нет ошибки диапазона. По той же логике, конечный страж 0xFFFFFF означает, что вы всегда найдете lower_bound.

...