Elliot
Elliot

Reputation: 493

Number of unique elements in a vector

If I have a vector of floats as {1.2,1.2,1.2,1.3,1.4} and I have to find out the number of unique elements, how can I do it?

I am new to C++ and I don't really know how to use iterators. Thanks!

Edit: I did something like this:

sort(arra.begin(),arra.end());
    vector <float>::iterator it = arra.begin();
    while ( it != arra.end() )
    {
        temp1 = *it;
        cout<<temp1<<"\n";
        it++;
        while (*it == temp1)
        {
            it++;
            cout<<*it<<"\n";
        }
        count++;
    }

But this gives a WA.

Upvotes: 2

Views: 12177

Answers (5)

Anton Savin
Anton Savin

Reputation: 41301

If it's OK to modify the vector (or you can make a copy of it):

std::sort(v.begin(), v.end());
auto uniqCnt = std::unique(v.begin(), v.end()) - v.begin();

Note that this may not work for floats because they don't represent the numbers exactly (but then you have to clarify what you mean by "unique elements" with respect to floats)

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

One of approaches is the following

#include <iostream>
#include <vector>
#include <set>

int main() 
{
    std::vector<double> v = { 1.2, 1.2, 1.2, 1.3, 1.4 };

    std::cout << "Number of unique elements is "
              << std::set<double>( v.begin(), v.end() ).size()
              << std::endl;

    return 0;
}

The output is

Number of unique elements is 3

If the vector is already sorted and not empty you can use the following approach

#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
#include <functional>

int main() 
{
    std::vector<double> v = { 1.2, 1.2, 1.2, 1.3, 1.4 };

    auto n = 1 + std::inner_product( std::next( v.begin() ), v.end(), 
                                     v.begin(), size_t( 0 ),
                                     std::plus<size_t>(), 
                                     std::not_equal_to<double>() );

    std::cout << "Number of unique elements is " << n << std::endl;

    return 0;
}

Or straightforward approach

#include <iostream>
#include <vector>

int main() 
{
    std::vector<double> v = { 1.2, 1.2, 1.2, 1.3, 1.4 };

    size_t n = 0;

    if ( v.begin() != v.end() )
    {
        ++n;
        for ( auto current = v.begin(), prev = v.begin(); 
             ++current != v.end(); ++prev )
        {
            if ( !( *prev < *current ) && !( *current < *prev ) ) ++n;
        }           
    }

    std::cout << "Number of unique elements is " << n << std::endl;

    return 0;
}

Upvotes: 10

Philip Stuyck
Philip Stuyck

Reputation: 7447

following works as well :

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

using namespace std;

typedef vector<double> doublevector;

int main()
{
    doublevector v = { 1.2, 1.2, 1.2, 1.3, 1.4 };

    sort(v.begin(), v.end()); //not needed if you know vector is sorted

    int nbrUnique = 0;
    if (v.size() == 1) nbrUnique = 1;
    else{
        nbrUnique = 1;
        for (doublevector::iterator it = v.begin(); it < v.end() - 1; ++it){
            if ((*it) != *(it + 1)) nbrUnique++;
        }
    }
    cout << nbrUnique << endl;

    return 0;
}

Upvotes: 0

Cereal_Killer
Cereal_Killer

Reputation: 324

Instead is using vector use set. It always keeps the unique element in it.

Read this example for how to find out unique element in vector.

Upvotes: 0

Andreas Vennstr&#246;m
Andreas Vennstr&#246;m

Reputation: 715

Something like this would work.

std::vector< float > vec = { 1.2f, 1.2f, 1.2f, 1.3f, 1.4f };
int unique_elements = 0;

{
    std::vector< float > used;
    for ( std::vector< float >::const_iterator it = vec.cbegin(); it != vec.cend(); ++it )
    {
        if ( std::find( used.cbegin(), used.cend(), *it ) == used.cend() )
        {
            used.push_back( *it );
            ++unique_elements;
        }
    }
}

Upvotes: 0

Related Questions