(⊙o⊙)…有空該學學STL了
原文地址:http://www.cnblogs.com/heyonggang/archive/2013/08/07/3243477.html
一.unique函數
類屬性算法unique的作用是從輸入序列中“刪除”所有相鄰的重複元素。
該算法刪除相鄰的重複元素,然後重新排列輸入範圍內的元素,並且返回一個迭代器(容器的長度沒變,只是元素順序改變了),表示無重複的值範圍得結束。
1 // sort words alphabetically so we can find the duplicates 2 sort(words.begin(), words.end()); 3 /* eliminate duplicate words: 4 * unique reorders words so that each word appears once in the 5 * front portion of words and returns an iterator one past the 6 unique range; 7 * erase uses a vector operation to remove the nonunique elements 8 */ 9 vector<string>::iterator end_unique = unique(words.begin(), words.end()); 10 words.erase(end_unique, words.end());
在STL中unique函數是一個去重函數, unique的功能是去除相鄰的重複元素(只保留一個),其實它並不真正把重複的元素刪除,是把重複的元素移到後面去了,然後依然保存到了原數組中,然後 返回去重後最後一個元素的地址,因爲unique去除的是相鄰的重複元素,所以一般用之前都會要排一下序。 |
若調用sort後,vector的對象的元素按次序排列如下:
sort jumps over quick red red slow the the turtle
則調用unique後,vector中存儲的內容是:
注意,words的大小並沒有改變,依然保存着10個元素;只是這些元素的順序改變了。調用unique“刪除”了相鄰的重複值。給“刪除”加上引號是因爲unique實際上並沒有刪除任何元素,而是將無重複的元素複製到序列的前段,從而覆蓋相鄰的重複元素。unique返回的迭代器指向超出無重複的元素範圍末端的下一個位置。
注意:算法不直接修改容器的大小。如果需要添加或刪除元素,則必須使用容器操作。
example:
1 #include <iostream> 2 #include <cassert> 3 #include <algorithm> 4 #include <vector> 5 #include <string> 6 #include <iterator> 7 using namespace std; 8 9 int main() 10 { 11 //cout<<"Illustrating the generic unique algorithm."<<endl; 12 const int N=11; 13 int array1[N]={1,2,0,3,3,0,7,7,7,0,8}; 14 vector<int> vector1; 15 for (int i=0;i<N;++i) 16 vector1.push_back(array1[i]); 17 18 vector<int>::iterator new_end; 19 new_end=unique(vector1.begin(),vector1.end()); //"刪除"相鄰的重複元素 20 assert(vector1.size()==N); 21 22 vector1.erase(new_end,vector1.end()); //刪除(真正的刪除)重複的元素 23 copy(vector1.begin(),vector1.end(),ostream_iterator<int>(cout," ")); 24 cout<<endl; 25 26 return 0; 27 }
運行結果爲:
二、unique_copy函數
算法標準庫定義了一個名爲unique_copy的函數,其操作類似於unique。
唯一的區別在於:前者接受第三個迭代器實參,用於指定複製不重複元素的目標序列。
unique_copy根據字面意思就是去除重複元素再執行copy運算。
編寫程序使用unique_copy將一個list對象中不重複的元素賦值到一個空的vector對象中。
1 //使用unique_copy算法 2 //將一個list對象中不重複的元素賦值到一個空的vector對象中 3 #include<iostream> 4 #include<list> 5 #include<vector> 6 #include<algorithm> 7 using namespace std; 8 9 int main() 10 { 11 int ia[7] = {5 , 2 , 2 , 2 , 100 , 5 , 2}; 12 list<int> ilst(ia , ia + 7); 13 vector<int> ivec; 14 15 //將list對象ilst中不重複的元素複製到空的vector對象ivec中 16 //sort(ilst.begin() , ilst.end()); //不能用此種排序,會報錯 17 ilst.sort(); //在進行復制之前要先排序,切記 18 unique_copy(ilst.begin() , ilst.end() , back_inserter(ivec)); 19 20 //輸出vector容器 21 cout<<"vector: "<<endl; 22 for(vector<int>::iterator iter = ivec.begin() ; iter != ivec.end() ; ++iter) 23 cout<<*iter<<" "; 24 cout<<endl; 25 26 return 0; 27 }
假如
list<int> ilst(ia , ia + 7); 改爲:vector<int> ilst(ia , ia + 7);
則排序時可用:
sort(ilst.begin() , ilst.end());
這裏要注意list和vector的排序用什麼方法。
《Effective STL》裏這些話可能有用處: item 31 “我們總結一下你的排序選擇: ● 如果你需要在vector、string、deque或數組上進行完全排序,你可以使用sort或stable_sort。 ● 如果你有一個vector、string、deque或數組,你只需要排序前n個元素,應該用partial_sort。 ● 如果你有一個vector、string、deque或數組,你需要鑑別出第n個元素或你需要鑑別出最前的n個元素,而不用知道它們的順序,nth_element是你應該注意和調用的。 ● 如果你需要把標準序列容器的元素或數組分隔爲滿足和不滿足某個標準,你大概就要找partition或stable_partition。 ● 如果你的數據是在list中,你可以直接使用partition和stable_partition,你可以使用list的sort來代替sort和stable_sort。如果你需要partial_sort或nth_element提供的效果,你就必須間接完成這個任務,但正如我在上面勾畫的,會有很多選擇。 另外,你可以通過把數據放在標準關聯容器中的方法以保持在任何時候東西都有序。你也可能會考慮標準非STL容器priority_queue,它也可以總是保持它的元素有序