1. 程式人生 > >2.5 有序向量的唯一化實現

2.5 有序向量的唯一化實現

無序 shrink n) 提高效率 TE 十分 i++ != 後者

有序向量的唯一化和無序向量不同,分為低效版和高效版。低效版代碼如下: template <typename T> int Vector<T>::uniquify() { int oldSize = _size; int i = 1; while (i < _size) { _elem[i - 1] == _elem[i] ? remove(i) : i++; } return oldSize - _size;
} 該算法的正確性在於有序算法中的重復元素必然是緊鄰的,所以只要自前向後逐個掃描再使用remove()接口刪除靠後者,否則轉向下一個元素,如此即可實現有序向量的唯一化。 這種算法的時間消耗主要來自於while循環,叠代次數是n-1次,且在最壞情況下每次循環都需要執行一次remove操作,所以共計有: (n-2) + (n-3) + (n-4) +...+2 + 1 = O(n*n) 由此可見,效率竟然和無序元素相同,所以十分低下,原因在於,在對remove()接口的調用過程中,同意元素作為後繼元素向前多次移動,且每次只移動一個單元。這是因為每次進行remove()操作的時候,我們只會進行一對一的獨立刪除。所以倘若我們成批的刪除重復元素必將大大提高效率。 由此給出高效版的代碼如下: template <typename T> int Vector<T>::uniquify() {
Rank i = 0, j = 0; while (++j < _size) { if (_elem[i] != _elem[j]) { _elem[++i] = _elem[j];//發現不同元素時,向前移至緊鄰於前者右側 } _size = ++i; shrink();//直接截除尾部多余元素 } return j - i;
} 這份算法的while循環的每次叠代只需要進行一次比較,向後移動一到兩個位置指針,並至多向前復制一個元素,故一次叠代只需要常數時間,總體只需要O(n)的時間。

2.5 有序向量的唯一化實現