STL unique != MATLAB unique

Alec Jacobson

March 26, 2012

weblog/

Got burned on the STL unique algorithm not actually implementing what I inferred its name to mean. In MATLAB unique is finds unique elements in an unordered set.
unique([1 2 3 3 2 1]) --> [1 2 3]
In STL, unique reorders an ordered set so that repeated equal entries are replaced with a single entry:
unique([1 2 3 3 2 1]) --> [1 2 3 2 1]
To get the behavior of the matlab unique you'll need to sort first.
#!/bin/bash
/*/../bin/ls > /dev/null
# BEGIN BASH SCRIPT
printf "//" | cat - $0 | g++ -I/opt/local/include/eigen3 -I$IGL_LIB/include -o .main -x c++ - && ./.main
rm -f .main
# END BASH SCRIPT
exit
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main(int argc,char * argv[])
{
  using namespace std;
  vector<int> V;
  V.push_back(1);
  V.push_back(2);
  V.push_back(3);
  V.push_back(3);
  V.push_back(2);
  V.push_back(1);
  vector<int> SV = V;

  cout<<"V=";
  copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
  cout<<endl;

  V.erase(unique(V.begin(), V.end()), V.end());
  cout<<"unique(V)=";
  copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
  cout<<endl;

  sort(SV.begin(),SV.end());
  SV.erase(unique(SV.begin(), SV.end()), SV.end());
  cout<<"unique(sort(V))=";
  copy(SV.begin(), SV.end(), ostream_iterator<int>(cout, " "));
  cout<<endl;

  return 0;
}
which produces:
V=1 2 3 3 2 1 
unique(V)=1 2 3 2 1 
unique(sort(V))=1 2 3