HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Is_permutation() on sequence containers in O(n) complexity - follow-up

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
sequenceis_permutationfollowcontainerscomplexity

Problem

This question is a continuation of my previous question:

Check is_permutation on a pair of same sized arrays.

I improved the implementation to generalize for all sequence containers. Please let me know how I can improve this implementation again.

```
#include
#include
#include
#include
#include

template
std::unordered_map count_frequency( T1 first, T1 last )
{
std::unordered_map temp_unordered_map;
auto temp_unordered_map_end = std::end( temp_unordered_map );
while( first != last )
{
auto it_temp_unordered_map = temp_unordered_map.find( *first );
if( it_temp_unordered_map == temp_unordered_map_end )
{
temp_unordered_map.emplace( *first, 1 );
}
else
{
++( it_temp_unordered_map->second );
}
++first;
}
return temp_unordered_map;
}

template
bool is_permutation( const T1 first1, const T1 last1, const T2 first2, const T2 last2 )
{
if( std::distance( first1, last1 ) != std::distance( first2, last2 ) )
{
return false;
}
std::unordered_map first_map = count_frequency( first1, last1 );
std::unordered_map second_map = count_frequency( first2, last2 );

std::pair::iterator,std::unordered_map::iterator > myPair=
std::mismatch( std::begin( first_map ), std::end( first_map ), std::begin( second_map ),
[]( std::pair& seed1, std::pair & seed2)
{ return seed1.second == seed2.second; }
);

return myPair.first == first_map.end() && myPair.second == second_map.end();
}

int main()
{
const std::array array1 { { 1, 3, 2, 4, 5 } };
const std::array array2 { { 1, 2, 4, 3 } };

if( ::is_permutation( std::begin( array1 ), std::end( array1 ), std::begin( array2 ), std::end( array2 ) ) )
{
std::cout vec1 { { 1, 3, 2, 4 } };
const std::vector vec2 { { 1, 2, 4, 3 } };

if( ::is_permutation( std::begin( vec1 ), std::end( vec1 ), std::begi

Solution

I would initially agree that the complexity of your solution is O(n), though, there are extreme cases where the performance of your count_frequency could be greater - unordered_map.emplace() is 'average case constant time, worst case linear', I don't believe a worst-case situation would happen for you.

Note that you have a very complicated equality-check comparing your two frequency-maps.... you have:

if( std::distance( first1, last1 ) != std::distance( first2, last2 ) )
{
    return false;  
}
std::unordered_map first_map = count_frequency( first1, last1 );        
std::unordered_map second_map = count_frequency( first2, last2 );

std::pair::iterator,std::unordered_map::iterator > myPair=
    std::mismatch( std::begin( first_map ), std::end( first_map ), std::begin( second_map ), 
    []( std::pair& seed1, std::pair & seed2) 
    { return seed1.second == seed2.second; }
    );

return  myPair.first == first_map.end() && myPair.second == second_map.end();


as far as I can tell, the size-check is redundant, and the rest can be simply:

template 
bool is_permutation( const T1 first1, const T1 last1, const T2 first2, const T2 last2 )
{   
    return count_frequency( first1, last1 ) == count_frequency( first2, last2 );
}


I put your code in this ideone, and the replacement code in this ideone here.

Code Snippets

if( std::distance( first1, last1 ) != std::distance( first2, last2 ) )
{
    return false;  
}
std::unordered_map< int, int > first_map = count_frequency( first1, last1 );        
std::unordered_map< int, int > second_map = count_frequency( first2, last2 );

std::pair<std::unordered_map< int, int >::iterator,std::unordered_map< int, int >::iterator > myPair=
    std::mismatch( std::begin( first_map ), std::end( first_map ), std::begin( second_map ), 
    []( std::pair< const int, int >& seed1, std::pair< const int, int > & seed2) 
    { return seed1.second == seed2.second; }
    );

return  myPair.first == first_map.end() && myPair.second == second_map.end();
template < typename T1, typename T2 >
bool is_permutation( const T1 first1, const T1 last1, const T2 first2, const T2 last2 )
{   
    return count_frequency( first1, last1 ) == count_frequency( first2, last2 );
}

Context

StackExchange Code Review Q#86241, answer score: 3

Revisions (0)

No revisions yet.