young03600
young03600

Reputation: 5

a pointer points to an object in vector after sorting(C++)

There are structs like these


class Component {
    string name;
    int x;
    int y;
};

struct Relation_h { // also for Relation_v (h for horizontal, v for vertical)
    Component *;
    //some data in here;
};

I have a initial vector vector<Component> data and vector<list<Relation>> relation_h and relation_v

I want to sort the vector data corresponding to its x and y respectively then construct the relations
and the Component* actually points to the data[i] for i in range(0, data.size())

But the problem is that the pointer points to is not the original object which I want to access after sorting with x and y

Is there way to deal with this situation?

Upvotes: 0

Views: 413

Answers (1)

PaulMcKenzie
PaulMcKenzie

Reputation: 35454

One such solution (but of course, not the only one) as mentioned in the comments is to use an auxiliary index array as described in this answer

#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
#include <numeric>

//...
struct Component {
    std::string name;
    int x;
    int y;
    Component(int val1, int val2) : x(val1), y(val2) {}
};
//...
int main()
{
    std::vector<Component> vComponents = { {2,3},{1,2},{0,2},{12,-2},{3,4},{-6,1} };

    // Create the index array (0,1,2,3,4,...)
    std::vector<int> index(vComponents.size());
    std::iota(index.begin(), index.end(), 0);

    //Print original
    std::cout << "Original order:\n";
    for (auto i : index)
        std::cout << vComponents[i].x << " " << vComponents[i].y << "\n";

    // Sort the index array, based on the x, y criteria
    std::sort(index.begin(), index.end(), [&](int n1, int n2)
        { return std::tie(vComponents[n1].x, vComponents[n1].y) <
                 std::tie(vComponents[n2].x, vComponents[n2].y); });
    //...
    // Print sorted
    std::cout << "\nSorted order:\n";
    for (auto i : index)
        std::cout << vComponents[i].x << " " << vComponents[i].y << ":    Location is at " << i << "\n";
}

Output:

Original order:
2 3
1 2
0 2
12 -2
3 4
-6 1

Sorted order:
-6 1:    Location is at 5
0 2:    Location is at 2
1 2:    Location is at 1
2 3:    Location is at 0
3 4:    Location is at 4
12 -2:    Location is at 3

There are a few things to note:

  1. The index array is the array that's sorted. The indices given to the std::sort predicate are used for the comparison within the vComponents vector.

  2. The usage of std::tie makes it trivial to compare "cascading" members, such as x and then y.

You then use the index array to access the elements. You keep the order of the elements intact, but have the index array that indicates where the "sorted" item is located.

Upvotes: 1

Related Questions