2011-04-19 61 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