2014-12-05 48 views
4

我有一個像下面結構件的載體:刪除備份結構成員:: vector的

struct pnt 
{ 
    bool has; 
    int num; 
}; 
std::vector<pnt> myvector; 

讓我們有這樣一個樣本向量:

myvector (num): 3 4 4 3 5 5 7 8 9 10 10             
myvector (has): 1 1 0 1 0 1 0 0 0 1 0 

我想要做的是找到重複的成員(根據具有相同的int num),並用false bool成員刪除。 讓自己的矢量變成了這個樣子:

myvector (num): 3 4 3 5 7 8 9 10               
myvector (has): 1 1 1 1 0 0 0 1 

這樣做,我寫如下功能:

void removeDuplicatedPnt(pnt_vec& myvector) 
{ 
    std::vector<pnt>::iterator pnt_iter; 
    for(pnt_iter = myvector.begin(); pnt_iter != myvector.end(); ++pnt_iter) 
    { 
     if(pnt_iter->has) 
     { 
      if(pnt_iter->num == (pnt_iter+1)->num) 
      { 
       myvector.erase(pnt_iter+1); 
      } 
      if(pnt_iter == myvector.begin()) 
      { 
      continue; 
      } 
      if(pnt_iter->num == (pnt_iter-1)->num) 
      { 
       myvector.erase(pnt_iter-1); 
       pnt_iter++; 
      } 
     } 
    } 
} 

我還可以通過會員的順序檢查做到這一點。但真正的矢量可能會很長。所以這就是爲什麼我第一次去找到真正的布爾成員,然後我檢查了下一個和上一個成員。問題是我如何在效率和穩健性方面修改上述代碼。

注意:我只能使用C++ 03(不是C++ 11)。我也可以使用噓聲(版本1.53),所以如果覺得在那裏有任何有用的功能,請放心。 :)

+0

http://stackoverflow.com/questions/tagged/erase-remove-idiom HTTP:// EN .m.wikipedia.org/wiki/Erase-remove_idiom – 2014-12-05 14:10:55

+0

'if(pnt_iter-> num ==(pnt_iter-1) - > num)'如果'pnt_iter'是矢量中的第一項,這將失敗。 – PaulMcKenzie 2014-12-05 14:15:26

+0

@dasblinkenlight對不起,我編輯了問題 – 2014-12-05 14:18:02

回答

2

你可以使用這個算法只切向有關:

  • 收集所有num S其中hastrueset<int>
  • 通過您vector<pnt>再去吧,刪除hasfalsenum的所有條目存在於set<int>

這裏s是一個示例實現:

struct filter { 
    set<int> seen; 
    bool operator()(const pnt& p) { 
     return !p.has && (seen.find(p.num) != seen.end()); 
    } 
}; 
... 
filter f; 
for (vector<pnt>::const_iterator i = v.begin() ; i != v.end() ; i++) { 
    if (i->has) { 
     f.seen.insert(i->num); 
    } 
} 
v.erase(remove_if(v.begin(), v.end(), f), v.end()); 

Demo.

1

您可以使用std ::排序和std ::使用自定義比較謂詞獨特:

[](const pnt& a, const pnt& b) { return a.num < b.num; } 

下面是使用Boost範圍,以減少打字演示它的快捷方法:

更新 C++ 03版Live On Coliru

#include <boost/range.hpp> 
#include <boost/range/algorithm.hpp> 
#include <iostream> 

using namespace boost; 

struct pnt { 
    int num; 
    bool has; 

    pnt(int num = 0, bool has = false) : num(num), has(has) {} 

    friend bool operator<(pnt const& a, pnt const& b) { return a.num<b.num; } 
    friend bool operator==(pnt const& a, pnt const& b) { return a.num==b.num; } 
}; 

int main() { 
    std::vector<pnt> v { {10,0 },{10,1 },{9,0 },{8,0 },{7,0 },{5,1 },{5,0 },{3,1 },{4,0 },{4,1 },{3,1 } }; 

    for (pnt p : boost::unique(boost::sort(v))) 
     std::cout << "{ num:" << p.num << ", has:" << p.has << "}\n"; 
} 

這實際ly有一些微妙的點,可以使例如做

it = std::find(v.begin(), v.end(), 3); // find a `pnt` with `num==3` 

但這

+0

@dasblinkenlight我正在修復我的答案是C++ 03。請注意,你也正在整理他的矢量。在一組:)(我知道這是不同的,但它不是很大) – sehe 2014-12-05 15:06:11

+0

「排序」我的意思是改變向量本身的項目順序。我只爲'num'部分使用'set',並將其與矢量本身分開存儲。我希望我可以使用unordered_set和lambdas,但它都是C++ 11 :-( – dasblinkenlight 2014-12-05 15:11:08

+0

@dasblinkenlight我打賭,使用'unordered_set'只會(一)增加噪聲和支持代碼('std :: hash '.. )(b)讓它慢一點對於OP中的情況,即使你需要對副本進行排序,我也沒有預料到任何東西都比載體快,但我承認我懶得證明它:) – sehe 2014-12-05 15:12:46