2011-10-20 40 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迭代器可能會在這個和類似的算法上失敗。 –