1

I need to keep only the unique arrays in a vector. I am not getting how to do it just using std algorithms. I tried different approaches, but nothing worked.

Code:

include <iostream>
#include <vector>
#include <array>
#include <algorithm>
using vec3 = std::array<int,3>;

struct vec3comp{
    bool operator()(const vec3 &lhs, const vec3 &rhs){
        return lhs[0]< rhs[0] && lhs[1] < rhs[1] && lhs[2] < rhs[2];
    }
} mycomp;

int main(){

    std::vector<std::array<int,3>>vec;
    
    vec.push_back({1,2,3});
    vec.push_back({1,3,2});
    vec.push_back({2,1,3});
    vec.push_back({1,3,3});
    vec.push_back({1,2,3});
    vec.push_back({1,2,4});
    vec.push_back({2,4,5});
    vec.push_back({3,5,6});
    vec.push_back({4,5,6});
    vec.push_back({5,4,6});
    vec.push_back({6,4,5});
    vec.push_back({5,4,3});
    vec.push_back({5,4,2});
    vec.push_back({5,4,6});
    vec.push_back({2,4,5});
    vec.push_back({3,5,6});
    vec.push_back({1,3,3});
    vec.push_back({2,1,3});
    //How should be the comp function 
   

     
        std::sort(vec.begin(),vec.end(),mycomp);
     for(auto i(0);i<vec.size();++i){
         std::cout<<vec.at(i)[0]<<" "<<vec.at(i)[1]<<" "<<vec.at(i)[2]<<std::endl;
     }
    //apply unique on vec after sort

    std::cout<<vec.size()<<std::endl;

    
    return 0;
}

After sorting and unique, vector of arrays should be:

{{1,2,3},{1,2,4},{1,3,2},{1,3,3},{2,1,3},{2,4,5},{3,4,5},{3,5,6},{4,5,6},{5,4,2},{5,4,3},{5,4,6},{6,4,5}}

Could someone help me with this problem?

Thanks in advance

Monster
  • 13
  • 3
  • 1
    [std::unique](https://en.cppreference.com/w/cpp/algorithm/unique) – m88 Feb 24 '21 at 09:42
  • @m88 First I need to make sure sorting is done correctly. before applying unique. In my case sorting is not done correctly. – Monster Feb 24 '21 at 09:47
  • 1
    Your `vec3comp` is wrong (doesn't respect [strict weak ordering](https://en.wikipedia.org/wiki/Weak_ordering)) (whereas default one does). – Jarod42 Feb 24 '21 at 10:12
  • Related to [operator-and-strict-weak-ordering](https://stackoverflow.com/questions/979759/operator-and-strict-weak-ordering) – Jarod42 Feb 24 '21 at 10:15

2 Answers2

1

using a std::set should solve your problem

std::set<vec3> s{vec.begin(),vec.end()};
vec.assign(s.begin(),s.end());

you can also add a custom compare class as a template parameter

tommy
  • 174
  • 1
  • 5
1

in the <algorithm> there is a function std::unique which deletes all identical consecutive elements therefore after sorting it is simple enough to use it then to delete all superfluous elements

So your code may looks like this

std::vector<std::array<int,3>>vec;
    
vec.push_back({1,2,3});
vec.push_back({1,3,2});
vec.push_back({1,2,3});
//and so on


std::sort(vec.begin(),vec.end(),mycomp);

//make all elements unique
auto it = std::unique(vec.begin(), vec.end());
vec.erase(it, a.end());

for(auto i(0);i<vec.size();++i){
     std::cout<<vec.at(i)[0]<<" "<<vec.at(i)[1]<<" "<<vec.at(i)[2]<<std::endl;
}

std::cout<<vec.size()<<std::endl;

P.S. I assumed that after sorting all the same items will go in sequence

Deumaudit
  • 978
  • 7
  • 17