最近聽某位大佬常說:「嘿,你用過unique函式沒有?」其實小良本身是不喜歡大量的去使用函式的,因為很多函式都有他的弊端,如果你不是十分清楚某些函式的具體實現的話,建議不要隨便使用某些你只知道大概功能的函式哦!
這個unique函式,人們都說他有去重的功能,仔細思考一下,會是如何去重的呢?
方法一:
我們可以搞個很暴力的解法:
對於每乙個元素,都去在這個元素之前的元素裡查詢是否出現過與之相同的元素,如果有,則remove!這個複雜度很高的,達到了o(n^2)!這麼低效的演算法想必各位大佬也沒興趣看,所以小良也不去展示這個**了。
方法二:
我們可以定義兩個下標:i 、j,起初 i 和 j 都指向同乙個元素,然後開始移動 j,如果發現第乙個a[i] != a[j]
的 j,就讓a[j]成為第 i 個元素的後繼!這樣可以做到對於大規模重複時的元素批量刪除演算法。
**如下:
void fun()
當然咯,在有必要的情況下,可以釋放空間!
int main()
unique(v.begin(), v.end());
vector::iterator it;
for(it = v.begin();it != v.end();it++)
cout << *it << ' ';
return 0;
}
這個**意思很明朗,但是輸出的結果很讓人詫異:
input :
101 2 2 3 3 3 7 8 9 10
output:
1 2 3 7 8 9 10 8 9 10
首先可以很明顯的看到:即便是使用的unique函式,vector的規模並沒有發生任何變化,還是10個數。但是我們發現,前面重複的部分確實是刪除了,不過後面卻新增了三個元素:8 9 10,這是為什麼呢?
經過查閱資料,我們得知:stl裡的unique函式,為了做到刪除操作,把下乙個不重複的元素移到了前面最靠近不同元素的位置,這樣也和上面我寫的第二種批量去重方法吻合。我們不妨來試著模擬一下這個過程:
首先輸入的是:
1 2 2 3 3 3 7 8 9 10
第一步:
2這個元素重複了,所以把下標 i 定在第三個元素,開始查詢不同於2的元素,很快在 j = 3的元素:3的位置就查到了!於是批量刪除,把3直接覆蓋上去:
1 2 3 3 3 3 7 8 9 10
第二步:
同上:1 2 3 7 3 3 3 8 9 10
第三步:
1 2 3 7 8 3 3 8 9 10
第四步:
1 2 3 7 8 9 3 8 9 10
第五步:
1 2 3 7 8 9 10 8 9 10
綜上所述:
這才有了最終的答案:1 2 3 7 8 9 10 8 9 10
我們可以很容易發現上面重複的元素一共加起來有3個,而我們後面冗餘的元素恰好也是三個,於是只需要讓:_size = _size - 3即可!
然而非常重要的是它的返回值:
返回的是無重複序列的最後乙個元素的位址!!!!
如果我寫上這麼一句話:_size = unique(a, a + n) - a
,這是在陣列裡使用unique函式,減去a的結果自然而然就是把位址轉換成長度,相當於無重複序列的長度。
在陣列中實現:
int main()
如果是在vector裡使用unique函式呢?
int main()
上述**中,我們首先設乙個迭代器(即之前說的位址),然後使用迭代器訪問的方式來輸出無重複序列,這樣的好處就和之前講的一樣,避開了後面冗餘的元素!而這個操作的實現方法,就是最開始講述的:」批量去重,下標替換「 的操作! unique函式的使用
unique的作用是 去掉 容器中相鄰元素的重複元素 一般要求陣列有序 它會把重複的元素新增到容器末尾 所以陣列大小並沒有改變 而返回值是去重之後的尾位址。用法 unique 陣列首位址,陣列尾位址 include include include using namespace std int ma...
C 中unique函式的用法總結
個人感覺,unique是stl中很實用的函式之一,需要 include,下面來簡單介紹一下它的作用。unique的作用是 去掉 容器中相鄰元素的重複元素,這裡去掉要加乙個引號,為什麼呢,是因為它實質上是乙個偽去除,它會把重複的元素新增到容器末尾,而返回值是去重之後的尾位址 是位址!舉個例子 int ...
unique函式的使用方法(STL庫函式)
unique函式 unique 函式是乙個去重函式,stl中unique的函式unique的功能是去除相鄰的重複元素 只保留乙個 還有乙個容易忽視的特性是它並不真正把重複的元素刪除。他是c 中的函式,所以標頭檔案要加 include,具體用法如下 int num 10 unique num,nun ...