最近項目遇到一個問題,有關stl vector自定義類型的去重問題。
背景:1、在一個vector中,存在大量元素擁有同一屬性,而其他屬性我們不關心,為了減少數據包大小,需要去重
2、此自定義類型不能去重載==操作符(公司代碼規范等原因)
3、正常情況下,vector中元素是有序的(擁有同一屬性的元素排在一起) /*引起誤解,之后補充*/
於是,花了十分鍾擼出了下列代碼原型。
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 5 using namespace std; 6 7 struct test 8 { 9 int key; 10 int value; 11 }; 12 13 class finder 14 { 15 public: 16 explicit finder(const test& _t):t(_t){} 17 const bool operator()(const test& __t)const{return t.key==__t.key;} 18 private: 19 test t; 20 }; 21 22 int main(void) 23 { 24 vector<test> vTest; 25 test t1 = {1,10}; 26 test t2 = {1,11}; 27 test t3 = {2,8}; 28 test t4 = {2,9}; 29 test t5 = {1,6}; 30 vTest.push_back(t1); 31 vTest.push_back(t2); 32 vTest.push_back(t3); 33 vTest.push_back(t4); 34 vTest.push_back(t5); 35 36 for(int index=0; index!=vTest.size(); ++index) 37 { 38 vTest.erase(find_if(vTest.begin(),vTest.end(),finder(vTest[index]))); 39 if(index == vTest.size()) 40 break; 41 } 42 43 for(int index=0; index!=vTest.size(); ++index) 44 cout<<vTest[index].key<<'\t'<<vTest[index].value<<endl; 45 46 return 0; 47 }
結果:
這里利用了一下仿函數(functor)來構造find_if的條件,達到查找具有相同屬性的自定義類型對象。
if里的判斷是為了防止segment fault,erase在刪除最后一個元素的時候,會給你帶來驚喜-_-(詳情請查看stl吧)。
目的達到了,但是總感覺循環太浪費CPU太低效太罪惡了,各位看官有沒有更好的辦法呢?求解。
================================================================
有小伙伴說用unique,好吧,其實之前也想到了,貌似效率沒啥提升,代碼還增加了。
貼代碼(所有):
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 5 using namespace std; 6 7 struct test 8 { 9 int key; 10 int value; 11 }; 12 13 class finder 14 { 15 public: 16 explicit finder(const test& _t):t(_t){} 17 const bool operator()(const test& __t)const{return t.key==__t.key;} 18 private: 19 test t; 20 }; 21 const bool unique_finder(const test& first, const test& second) 22 { 23 return first.key == second.key; 24 } 25 const bool sort_finder(const test& first, const test& second) 26 { 27 return first.key < second.key; 28 } 29 30 int main(void) 31 { 32 vector<test> vTest; 33 test t1 = {1,10}; 34 test t2 = {1,11}; 35 test t3 = {2,8}; 36 test t4 = {2,9}; 37 test t5 = {1,6}; 38 vTest.push_back(t1); 39 vTest.push_back(t2); 40 vTest.push_back(t3); 41 vTest.push_back(t4); 42 vTest.push_back(t5); 43 44 /* 45 for(int index=0; index!=vTest.size(); ++index) 46 { 47 vTest.erase(find_if(vTest.begin(),vTest.end(),finder(vTest[index]))); 48 if(index == vTest.size()) 49 break; 50 } 51 */ 52 53 cout<<"=================origin===================="<<endl; 54 for(int index=0; index!=vTest.size(); ++index) 55 cout<<vTest[index].key<<'\t'<<vTest[index].value<<endl; 56 57 cout<<"=================sort===================="<<endl; 58 sort(vTest.begin(),vTest.end(),sort_finder); 59 for(int index=0; index!=vTest.size(); ++index) 60 cout<<vTest[index].key<<'\t'<<vTest[index].value<<endl; 61 62 /* 63 cout<<"=================stable_sort===================="<<endl; 64 stable_sort(vTest.begin(),vTest.end(),sort_finder); 65 for(int index=0; index!=vTest.size(); ++index) 66 cout<<vTest[index].key<<'\t'<<vTest[index].value<<endl; 67 */ 68 69 cout<<"==================unique==================="<<endl; 70 vTest.erase(unique(vTest.begin(),vTest.end(),unique_finder),vTest.end()); 71 72 for(int index=0; index!=vTest.size(); ++index) 73 cout<<vTest[index].key<<'\t'<<vTest[index].value<<endl; 74 75 return 0; 76 }
結果:
嘿嘿,不錯,如果大家還有更好的辦法,可以提出來,謝謝!