I am using a datatype of std::vector
to store a 2D matrix/array. I would like to determine the unique rows of this matrix. I am l
EDIT: I forgot std::vector already defines operator<
and operator==
so you need not even use that:
template
std::vector > GetUniqueRows(std::vector > input)
{
std::sort(input.begin(), input.end());
input.erase(std::unique(input.begin(), input.end()), input.end());
return input;
}
Use std::unique
in concert with a custom functor which calls std::equal
on the two vectors.
std::unique
requires that the input be sorted first. Use a custom functor calling std::lexicographical_compare
on the two vectors input. If you need to recover the unreordered output, you'll need to store the existing order somehow. This will achieve M*n log n complexity for the sort operation (where M is the length of the inner vectors, n is the number of inner vectors), while the std::unique
call will take m*n
time.
For comparison, both your existing approaches are m*n^2 time.
EDIT: Example:
template
struct VectorEqual : std::binary_function&, const std::vector&, bool>
{
bool operator()(const std::vector& lhs, const std::vector& rhs)
{
if (lhs.size() != rhs.size()) return false;
return std::equal(lhs.first(), lhs.second(), rhs.first());
}
};
template
struct VectorLess : std::binary_function&, const std::vector&, bool>
{
bool operator()(const std::vector& lhs, const std::vector& rhs)
{
return std::lexicographical_compare(lhs.first(), lhs.second(), rhs.first(), rhs.second());
}
};
template
std::vector > GetUniqueRows(std::vector > input)
{
std::sort(input.begin(), input.end(), VectorLess());
input.erase(std::unique(input.begin(), input.end(), VectorEqual()), input.end());
return input;
}