2011-10-20 37 views
2

我正在使用std::unique在float vector中使用具有大epsilon的equals方法进行合并群集。问题是,它需要运行像1,并将其变为2
虽然我希望它合并它们像“等于”用点平均,这样使用他们变成3std ::唯一合并

(1) ...    .  .... ..... 
(2) .     .  .  . 
(3) .    .  .  . 

我该怎么办C++标准库?

+0

数据的格式是什么?它不能只是'std :: vector ',否则你会失去定位。除非我误解你。 –

+0

@MooingDuck:是的,值是位置。第一个像1,2,3,20,25,26,27,28,35,36,37,38,39。 – Dani

+0

“运行”总是连续的吗? –

回答

2

不,没有标准的算法可以做你想做的。然而,这并不是非常复杂。我试图对迭代器做出最小的假设,所以这应该适用于任何前向输入迭代器。

#include <iostream> 

template<class initer, class outiter, class predicate> 
outiter average_runs(initer begin, initer end, outiter out, predicate pred) { 
    //quit if no range 
    if (begin == end) 
     return out; 
    initer endrun = begin; 
    do { 
     //find end of run 
     while(endrun+1 != end && pred(*endrun,*(endrun+1))) 
      ++endrun; 
     //move "begin" to the middle 
     std::advance(begin, std::distance(begin,endrun)/2); 
     //output the result 
     *out++ = *begin; 
     //start next run 
     begin = ++endrun; 
    } while(endrun != end); 
    return out; 
} 

bool intclose(int l, int r) 
{ return r-l <= 1;} 
int main() { 
    int array[13] = {1,2,3,20,25,26,27,28,35,36,37,38,39}; 
    int output[13] = {}; 
    int* end = average_runs((int*)array, array+13, (int*)output, &intclose); 
    for(int* c = output; c<end; ++c) 
     std::cout << *c << ' '; 
    return 0; 
} 
//displays: 2 20 26 37 
+0

表达式'(endrun-begin)'不能保证用于前向迭代器。 – aschepler

+0

呃,纠正。 'std :: distance()'ftw! –

+0

另外我无法找到保证,如果'fwditer a = b;基础B ++; a ++;''a'和'b'“指向”相同的“位置”。这意味着istream迭代器可能会在这个和类似的算法上失败。 –