Monster
Monster

Reputation: 13

How to do sorting and applying unique on vector of vectors?

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

Upvotes: 1

Views: 208

Answers (2)

Deumaudit
Deumaudit

Reputation: 1016

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

Upvotes: 1

tommy
tommy

Reputation: 182

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

Upvotes: 1

Related Questions