2011-07-18 55 views
1

我試圖找到最接近的QMap RGB值(我知道它可能應該是單純皰疹病毒,但這不是問題)。以下是我走到這一步:地圖 - 尋找最近的價值?

 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這是確定的,但如果有一些值大於最大的索引,程序崩潰。我究竟做錯了什麼?

+0

您在地圖中是否使用自定義比較? – MSalters

+0

nope,無論如何它是QT庫中的'QMap'。 –

+0

好的,刪除STL標記(QMap是從Qt庫,而不是STL) – MSalters

回答

3

可能是因爲.value()試圖取消引用不存在的項目?

這看起來像自己的自定義地圖的實現(或包裝),但你的邏輯似乎是不正確

  1. 你叫lowerBound每一次 - 除非你正在尋找的產品在地圖第一
  2. 如果它是地圖中的第一個,則再次搜索?
  3. 如果不是你再次搜索(如果已經找到了,則再次重複該操作),否則如果找不到,尋找最近的(這是可以的),但是你是否處理沒有的情況(即在lowerBound) ?

的邏輯應該是這樣的:

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(); 
} 
+0

感謝它現在好了,但在什麼情況下可能會出現錯誤? –

+0

最有可能是因爲以下原因,'find()'返回'end()',因此你最終做一個'upperBound()' - 它也返回'end()' - .value()'),導致問題。 – Nim

+0

但我問你的代碼,你做onlny'lowerBound',所以也許我們應該檢查'begin()'? –

1

呼叫

images_map.upperBound(current_rgb) 

可能返回

images_map.end() 

在你不應該叫value()這種情況下。

0

您可以通過添加標記值0x0000000xFFFFFF(一次)來解決迭代器超出範圍問題。這樣,你總是有一個有效的下限和上限。當然,這可能會影響算法的結果。例如。如果您的「最小」真實顏色是純藍色(0x0000FF),則深藍色(0x00007F)現在將顯示黑色,而不是純藍色。當然,這通過兩次比較很容易解決。

隨着哨兵到位,請致電QMap::lower_bound。您需要檢查您是否確實找到了精確匹配:如果*lower_bound是您想要的值,請將其返回。否則,lower_bound指向比您的輸入大的第一個元素。因此,--lowerbound指向比輸入小的最後一個元素。檢查兩者中哪一個更近。

注意,只有這樣,lower_bound可以指向begin是當你輸入恰恰0x000000(定點),在這種情況下,你不會有機會--lower_bound。那裏沒有範圍錯誤。通過同樣的邏輯,最終哨兵0xFFFFFF意味着你總能找到一個lower_bound