'Unique pair in the Vector list C++

I have a vector of pairs of integers that looks somehow like that:

(0, 1) (1, 9) (0, 1) (2, 4) (1, 9) I want to extract unique pairfrom there, so that the result looks as follows: (0,1) (1,9) (2, 4)

At the moment I'm doing it like that:

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

std::vector<int> getElements(std::vector<std::pair<int, int>>& S) {
    std::vector<int> V;
    V.reserve(2 * S.size());
    for (const auto& i : S) {
        V.push_back(i.first);
        V.push_back(i.second);
    }
    std::sort(V.begin(), V.end());
    V.erase(std::unique(V.begin(), V.end()), V.end());
    return V;
}

int main()
{
    std::vector<std::pair<int, int>> v{ { 0, 1 },{ 1, 9 },{ 0, 1 },{ 2, 4 },{ 1, 9 } };

    for (const auto& i : getElements(v))
        std::cout << i << ' ';
    std::cout << '\n';
}

I am getting - ‍‍0‍, 1, 2, 4, 9

Any corrections in code will be helpful



Solution 1:[1]

There are a couple of issues in your code:

  1. getElements should return std::vector<std::pair<int, int>>, since you mentioned you would like to get the unique pairs.
  2. The last few lines of code in getElements is in the direction of the right solution. As you can see here: std::unique, sort followed by unique can be used to remove all duplicates. But all the code creating a vector of ints from the pairs should not be there.

See below a corrected version:

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

std::vector<std::pair<int, int>> getElements(std::vector<std::pair<int, int>> const & S) {
    auto V = S;
    std::sort(V.begin(), V.end());
    V.erase(std::unique(V.begin(), V.end()), V.end());
    return V;
}

int main()
{
    std::vector<std::pair<int, int>> v{ { 0, 1 },{ 1, 9 },{ 0, 1 },{ 2, 4 },{ 1, 9 } };
    for (const auto& i : getElements(v))
        std::cout << "(" << i.first << "," << i.second << ")  ";
    std::cout << std::endl;
}

Output:

(0,1)  (1,9)  (2,4)

Update: as @JHBonarius commented below, since getElements does not modify S, it is better to pass it by const & (see my updated code above).
This way the compiler will detect an erroneous attempt to modify it.

Solution 2:[2]

A well known 'list' transpose, applied to your example:

In [14]: alist = [[1,2],[3,4],[5,6]]
In [15]: alist
Out[15]: [[1, 2], [3, 4], [5, 6]]
In [16]: blist = list(zip(*alist))
In [17]: blist
Out[17]: [(1, 3, 5), (2, 4, 6)]

Applying numpy's transpose:

In [18]: np.transpose(alist)
Out[18]: 
array([[1, 3, 5],
       [2, 4, 6]])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2