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

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 
閱讀(
評論(
編輯 
收藏
Tags: