去重函式unique,sort,erase的應用

RioTian發表於2020-05-24

std::unique

一.總述

  unique函式屬於STL中比較常用函式,它的功能是元素去重。即”刪除”序列中所有相鄰的重複元素(只保留一個)。此處的刪除,並不

是真的刪除,而是指重複元素的位置被不重複的元素給佔領了。由於它”刪除”的是相鄰的重複元素,所以在使用unique函式之前,一般都

會將目標序列進行排序。

功能:對有序的容器重新排列,將第一次出現的元素從前往後排,其他重複出現的元素依次排在後面

二.函式原型

unique函式的函式原型如下:1.只有兩個引數,且引數型別都是迭代器:

iterator unique(iterator it_1,iterator it_2);

這種型別的unique函式是我們最常用的形式。其中這兩個參數列示對容器中[it_1,it_2)範圍的元素進行去重(注:區間是前閉後開,即不包含it_2所指的元素),返回值是一個迭代器,它指向的是去重後容器中不重複序列的最後一個元素的下一個元素。

有序的容器:

1 1 2 3 3 4 4 4 5 6

unique處理過的容器:

unique unique unique unique unique unique 迭代器指向的地址      
1 2 3 4 5 6 1 3 4 4

三、去重函式unique

標頭檔案:#include <algorithm>

unique的作用就是"去除"陣列中重複的元素,unique去重的過程是將重複的元素移到容器的後面去,實際上這種說法並不正確,應該是把不重複的元素移到前面來:

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. int main()
  5. {
  6. int a[10] = { 0, 7, 7, 6, 1, 1, 5, 5, 8, 9 };
  7. int n = unique(a, a + 10) - a;
  8. cout << n << endl; //7,得到不重複元素的個數;
  9. for (int i = 0; i < 10; i++)
  10. cout << a[i] << " "; //0 7 6 1 5 8 9 5 8 9
  11. return 0;
  12. }

可以看見最後三個元素是:5 8 9,而重複的數字是1 5 7,所以網上這種說法:“unique去重的過程是將重複的元素移到容器的後面去”是不對的。 
上面的n返回的是7,它就是:最後一個不重複數字的下標。 
所以,把上面的for迴圈改成:

  1. for (int i = 0; i < n; i++)
  2. cout << a[i] << " "; //0 7 6 1 5 8 9

i < n就是隻輸出前面不重複的數字,這樣就實現的去重的效果。

四、去重函式unique與排序函式sort結合

  如果先去重排序那麼結果就是:去重毫無作用。因為去重排序排序時會把重複的數字又放在了一起,所以要先排序去重。這點應該好理解,這裡就提一下。

排序去重程式碼如下:

  1. #include <iostream>
  2. #include <algorithm> //sort(), unique()
  3. #include <functional> //less<int>()
  4. using namespace std;
  5. int main()
  6. {
  7. int i;
  8. int a[10] = { 0, 7, 7, 6, 1, 1, 5, 5, 8, 9 };
  9. sort( a, a + 10, less<int>() ); //排序
  10. int n = unique(a, a + 10) - a; //去重
  11. for ( i = 0; i < n; i++) //注意i < n
  12. cout << a[i] << " "; //0 1 5 6 7 8 9
  13. }

於是就得到了想要的結果:先把數字排序,再去掉重複數字。

五,以上便是去重應用於陣列的情況:接下來看一下字串的情況:

uniqe()函式是去掉重複的字元。是指兩個字元連續出現就只留下一個,其餘的就刪除。例如:

 string s("hello,world");

 string::iterator iterEnd=unique(s.begin(),s.end());     //返回出現重複元素的迭代器位置

這程式碼執行後,s的值為helo,worldd. 只消除連續出現的同樣的字元。重點是不連續的不消除。

unique函式通常和erase函式一起使用,來達到刪除重複元素的目的。(注:此處的刪除是真正的刪除,即從容器中去除重複的元素,容器

的長度也發生了變換;而單純的使用unique函式的話,容器的長度並沒有發生變化,只是元素的位置發生了變化)

還有一個就是unqiue()函式刪除重複的字元後,字串長度不變,所以如果字串刪除字元後,後面按照之前的值填上。 所以就是helo,worldd,而不是helo,world;

所以就會有一個函式erase()函式存在的必要性了。它可以刪除字元。

s.erase(iterEnd,s.end());      //刪除掉重複元素;

執行後s的值就是我們想要的helo,world.

如果想要只留下一個字元l,只能先排序!!!!讓他們挨在一塊。

sort()函式是排序字串字元。 即如果是akjsc,排序後為acjks.

所以一般用unique函式的時候都會用到erase(). sort()用到也也比較多。

六,總結:

  1. #include <iostream>
  2. #include <algorithm> //sort(), unique()
  3. #include <functional> //less<int>()
  4. #include<string>
  5. using namespace std;
  6. int main()
  7. {
  8. /////////////////字串的去重排序
  9. string str = "sjscncmkzmxkz";
  10. sort(str.begin(), str.end()); //先對字串排序;
  11. string::iterator itend = unique(str.begin(), str.end()); //返回出現重複元素的首地址;
  12. cout << str << endl;
  13. str.erase(itend, str.end()); //刪除重複元素;
  14. cout << str << endl;
  15. ////////////陣列的去重排序;
  16. int a[10] = { 0, 7, 7, 6, 1, 1, 5, 5, 8, 9 };
  17. sort(a, a + 10, less<int>()); //排序
  18. int n = unique(a, a + 10) - a; //去重
  19. int n1 = distance(a, unique(a, a + n)); //獲得不重複元素的個數;
  20. for (int i = 0; i < n1; i++) //注意i < n
  21. cout << a[i] << " "; //0 1 5 6 7 8 9
  22. }

 

posted @ 2020-05-24 08:21  RioTian  閱讀(...)  評論(...編輯  收藏

相關文章