Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove duplicated items in a sorted vector

I currently have a vector<int> c which contains {1,2,2,4,5,5,6} and I want to remove the duplicated numbers so that c will have {1,4,6}. A lot of solutions on the internet seem to just remove one of the duplicates, but I'm trying to remove all occurrences of the duplicated number.

Assume c is always sorted.

I currently have

#include <iostream>
#include <vector>

int main() {
  vector<int> c{1,2,2,4,5,5,6};
  for (int i = 0; i < c.size()-1; i++) {
    for (int j=1; j<c.size();j++){
      if(c[i] == c[j]){
         // delete i and j? 
      }
    }
  }
}

I tried to use two for-loops so that I can compare the current element and the next element. This is where my doubt kicked in. I'm not sure if I'm approaching the problem correctly.

Could I get help on how to approach my problem?

like image 524
WhitneyD Avatar asked Dec 16 '20 18:12

WhitneyD


People also ask

How do I remove duplicates from a sorted vector?

A simple solution is to iterate the vector, and for each element, we delete all its duplicates from the vector if present. We can either write our own routine for this or use the std::remove algorithm that makes our code elegant. This approach takes constant space but runs in O(n2) time.

How do I remove duplicates from a filtered list?

In Excel, there are several ways to filter for unique values—or remove duplicate values: To filter for unique values, click Data > Sort & Filter > Advanced. To remove duplicate values, click Data > Data Tools > Remove Duplicates.

How do I get rid of duplicate elements?

We can remove duplicate element in an array by 2 ways: using temporary array or using separate index. To remove the duplicate element from array, the array must be in sorted order. If array is not sorted, you can sort it by calling Arrays. sort(arr) method.


2 Answers

Generally one has to be very careful when deleting from containers while iterating over them. C++ STL can do this easily and faster (on average) than using nested loops.

#include <vector> 
#include <algorithm>
#include <unordered_set>

int main() {
    std::vector<int> c{1,2,2,4,5,5,6};
    std::unordered_multiset<int> unique( c.begin(), c.end() );
    c.erase(std::remove_if(c.begin(),c.end(),[&](const auto& e){return unique.count(e)>1;}),c.end());

    for(auto e: c){
        std::cout<<e<<' ';
    }
}

//Output: 1 4 6

Alternatively, you could use std::map<int,std::size_t> and count the occurences this way.

like image 172
Quimby Avatar answered Oct 15 '22 19:10

Quimby


Use std::remove_if to move items occurring multiple times to the rear, then erase them.

#include <iostream>
#include <vector>
#include <algorithm>


int main()
{

    std::vector<int> V {1,2,2,4,5,5,6};

    auto it = std::remove_if(V.begin(), V.end(), [&](const auto& val) 
    { 
        return std::count(V.begin(), V.end(), val) > 1;
    });

    V.erase(it, V.end());

    for (const auto& val : V)
        std::cout << val << std::endl;
    
    return 0;
}

Output:

1
4
6

For demo: https://godbolt.org/z/j6fxe1

like image 41
Tony Tannous Avatar answered Oct 15 '22 18:10

Tony Tannous