2011-04-19 105 views
1

必須有一些算法,這將使這比我在做什麼容易...排序/合併相關的陣列

我有什麼是兩個數組,每兩列。兩者中的一列是時間戳,另一列是測量結果。

需要採取什麼措施是把它變成一個單一的陣列:時間戳,測量1,測量2

的問題是時間戳經常會不一致,完全是。一個數組可能在一段時間內完全缺失一個值,或者時間戳可能會被忽略(無足輕重,以至於將兩個測量分配給相同的時間戳)。

有沒有做這種模糊合併操作的一些衆所周知的方式?一個簡單的公共領域函數?

+0

這是功課?我不太瞭解你打算如何構建合併數組的規則。爲什麼你保持兩種測量? – 2011-04-19 22:27:08

+0

不作業:)測量是不同的,但相關。想象一下房間不同部位的兩個溫度探頭。如果一切都很完美,他們都會在同一時間採取並報告測量結果。但他們沒有。然而,我想一起在一個圖表上展示,但只能使用一個時間尺度。 – DougN 2011-04-19 22:31:58

+0

到目前爲止,我有兩個數組排序,從array1中獲取時間,並在array2中查找關閉時間。聽起來很簡單,但代碼越來越難看(試圖不遍歷整個array2每次)。必須是這種我不知道的模式... – DougN 2011-04-19 22:34:23

回答

1

首先問自己這些問題:數組是否具有相同數量的元素?你想如何結合兩個項目相同的時間戳?你想如何結合兩個不同時間戳的項目?

您可能需要自己編寫算法。類似這樣的操作很容易實現:

  1. 首先按照時間戳順序對每個數組進行排序。
  2. 分別在每個輸入數組的開頭聲明兩個迭代器,以及一個空輸出數組。
  3. 然後,檢查哪些數組具有最早的時間戳。早早叫它,另一個叫LATE。
    • 如果EARLY接近LATE(小於某個常量),則應用合併操作並將結果插入到輸出數組的末尾。增加兩個迭代器並返回3.
    • 否則,EARLY遠不是LATE。您需要處理LATE數組中的缺失值,可能是重複以前的值或使用某個函數對其進行插值。決定在輸出數組中插入還是不包含值。在這種情況下,您只增加EARLY數組迭代器並返回3.
  4. 如果您已達到任一數組的末尾,則其他數組的其餘部分爲LATE。您可能想將其解釋爲缺失值,並重復或插入測量值。
  5. 返回輸出數組。

OutputArray merge(InputArray& a, InputArray& b) { 
    InputArray::iterator a_it = a.begin(); 
    InputArray::iterator b_it = b.begin(); 
    while(a_it != a.end() && b_it != b.end()) { 
     InputArray::iterator& early = *a_it.timestamp < *b_it.timestamp ? a_it : b_it; 
     InputArray::iterator& late = *a_it.timestamp < *b_it.timestamp ? b_it : a_it; 
     if(*late.timestamp - *early.timestamp < TIMESTAMP_CLOSE_ENOUGH) { 
      output.timestamp = (*late.timestamp + *early.timestamp)/2; // mean value 
      output.measure1 = *a_it.measure; 
      output.measure2 = *b_it.measure; 
      outputArray.push_back(output); 
      a_it++; b_it++; 
     } 
     else { 
      output.timestamp = *early.timestamp; 
      output.measure1 = *a_it.timestamp < *b_it.timestamp ? *a_it.measure : outputArray.back.measure1; // previous value if missing 
      output.measure2 = *a_it.timestamp < *b_it.timestamp ? outputArray.back.measure2 : *b_it.measure; 
      outputArray.push_back(output); 
      early++; 
     } 
    } 

    InputArray::iterator& late = a_it != a.end() ? a_it : b_it; 
    InputArray::iterator late_end = a_it != a.end() ? a.end() : b.end(); 
    while(late != late_end) { 
      output.timestamp = *late.timestamp; 
      output.measure1 = a_it != a.end() ? *a_it.measure : outputArray.back.measure1; // previous value if missing 
      output.measure2 = a_it != a.end() ? outputArray.back.measure2 : *b_it.measure; 
      outputArray.push_back(output); 
      late++; 
    } 
    return outputArray; 
} 
+0

好方法。這正是我想要達成的,但是你的實現比我的更清晰! – DougN 2011-04-20 14:12:39

+0

嘿,謝謝。下一次考慮發佈你的實現的簡化版本,即使它有bug /甚至沒有編譯。代碼有時是表達自己的最佳方式:-) – 2011-04-20 16:48:59