Reputation: 493
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
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
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
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
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
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