C STL中的unique函式解析

2021-10-05 20:44:49 字數 3502 閱讀 9736

一.總述

unique函式屬於stl中比較常用函式,它的功能是元素去重。即」刪除」序列中所有相鄰的重複元素(只保留乙個)。此處的刪除,並不是真的刪除,而是指重複元素的位置被不重複的元素給占領了(詳細情況,下面會講)。由於它」刪除」的是相鄰的重複元素,所以在使用unique函式之前,一般都會將目標序列進行排序。

二.函式原型

unique函式的函式原型如下:

1.只有兩個引數,且引數型別都是迭代器:

iterator unique

(iterator it_1,iterator it_2)

;

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

2.有三個引數,且前兩個引數型別為迭代器,最後乙個引數型別可以看作是bool型別:

iterator unique

(iterator it_1,iterator it_2,

bool myfunc)

;

該型別的unique函式我們使用的比較少,其中前兩個引數和返回值同上面型別的unique函式是一樣的,主要區別在於第三個引數。這裡的第三個引數表示的是自定義元素是否相等。也就是說通過自定義兩個元素相等的規則,來對容器中元素進行去重。這裡的第三個引數與stl中sort函式的第三個引數功能類似(關於sort函式:關於第三個引數的詳細介紹,可以參考:

三.函式用法例項

上面介紹了unique函式的功能和原型,那麼,它到底是如何進行去重的呢?即「刪除」的具體操作是怎樣的呢?

關於這個問題,給了我們一種解釋,即unique函式是完全等價於下面這個函式的:

iterator my_unique (iterator first, iterator last)

return

++result;

}

分析這段**,我們可以知道,unique函式的去重過程實際上就是不停的把後面不重複的元素移到前面來,也可以說是用不重複的元素占領重複元素的位置。有了這段**我們可以結合例項來更好的理解這個函式了。

例項:

#include

#include

#include

using

namespace std;

static

bool

myfunc

(int i,

int j)

intmain()

; vector<

int>

::iterator it_1 = a.

begin()

; vector<

int>

::iterator it_2 = a.

end();

//sort(it_1,it_2);

cout<<

"去重前的 a : "

;for

(int i =

0; i < a.

size()

; i++

) cout<

; cout<

//it_h = unique(it_1,it_2);

//unique(it_1,it_2,myfunc);

unique

(it_1,it_2)

; cout<<

"去重後的 a : "

;for

(int i =

0; i < a.

size()

; i++

) cout<

; cout<

}

執行結果如下:

對於上面的結果,我們可以看到,容器中不重複的元素都移到了前面,至於後面的元素,實際上並沒有改變(這個過程只需結合my_unique函式來分析即可)。

注:1.有很多文章說的是,unique去重的過程是將重複的元素移到容器的後面去,實際上這種說法並不正確,應該是把不重複的元素移到前面來。

2.一定不要忘記的是,unique函式在使用前需要對容器中的元素進行排序(當然不是必須的,但我們絕大數情況下需要這麼做),由於本例中的元素已經是排好序的,所以此處我沒排序,但實際使用中不要忘記。

四.用法拓展

1.我們以上的例項針對的是函式原型1的用法,對於函式原型2,我們仍然使用上述例項,只不過unique的用法變成:

unique

(it_1,it_2,myfunc)

;

即自定義的元素相等的準則,其中myfunc在上述例項中有其原始碼,分析可知,只有i+1 == j的時候我們才認為i和j「相等」;例項結果如下:

也就是說,按照我們自定義的規則,這個例項中只有3和4」相等的」,4和5是」相等的」,5和6,6和7是」相等的」。所以最終結果是上圖的樣子。

2.unique函式通常和erase函式一起使用,來達到刪除重複元素的目的。(注:此處的刪除是真正的刪除,即從容器中去除重複的元素,容器的長度也發生了變換;而單純的使用unique函式的話,容器的長度並沒有發生變化,只是元素的位置發生了變化)關於erase函式的用法,可以參考:下面是乙個具體的例項:

#include

#include

#include

using

namespace std;

intmain()

; vector<

int>

::iterator it_1 = a.

begin()

; vector<

int>

::iterator it_2 = a.

end();

vector<

int>

::iterator new_end;

new_end =

unique

(it_1,it_2)

;//注意unique的返回值

a.erase

(new_end,it_2)

; cout<<

"刪除重複元素後的 a : "

;for

(int i =

0; i < a.

size()

; i++

) cout<

; cout<

}

執行結果如下:

可以看到,相比之前的結果,a的長度確實發生了改變,真正的刪除了a中的重複元素。

C STL中的unique函式解析

原作者的這篇博文寫的非常通俗易懂,做了個搬運工。unique函式屬於stl中比較常用函式,它的功能是元素去重。即 刪除 序列中所有相鄰的重複元素 只保留乙個 此處的刪除,並不是真的刪除,而是指重複元素的位置被不重複的元素給占領了 詳細情況,下面會講 由於它 刪除 的是相鄰的重複元素,所以在使用uni...

C 中的unique函式

切記,沒有排序前只是去掉相鄰的重複元素,如果要真正去重就要排序 現在總結一下unique,unique的作用是 去掉 容器中相鄰元素的重複元素 不一定要求陣列有序 它會把重複的元素新增到容器末尾 所以陣列大小並沒有改變 而返回值是去重之後的尾位址,下面舉個例子。由於返回的是容器末尾,所以如果想得到去...

C STL中的函式

標頭檔案 algorithm 中有很多好用的函式 max a,b 返回a和b中的最大值,引數可以是浮點數 min a,b 返回a和b中的最小值,引數可以是浮點數 tolower char ch 將字元型變數ch的大寫轉換為小寫,其他不變 toupper char ch 將字元型變數ch的小寫轉換為大...