3

How do I make a set where the elements are always ordered using some local variable?

A simplified example of what I am trying to do is this.

int x[5] {9, 2, 3, 1, 8};
set<int, ???> my_set;
my_set.insert(0);
my_set.insert(1);
my_set.insert(4);
for (int a : my_set)
    cout << a << " ";   // I want the answer 1 4 0 because x[1] < x[4] < x[0]

I think I might be able to do this using a struct, but I am unsure how the use of x changes things.

cpp beginner
  • 512
  • 6
  • 23
  • Your pseudo code is hard to follow. You have an `int` array denoted by `x`, yet you insert `int` literals into your set. Then your comment says "because x[1] < x[4] < x[0]" yet you never use `x` in your pseudo code. You also don't address what `???` means. I don't think you need another type parameter other than `int`. – Jonny Henly May 11 '16 at 21:17
  • See http://stackoverflow.com/questions/2620862/using-custom-stdset-comparator – Captain Obvlious May 11 '16 at 21:21
  • @JonnyHenly Sorry you're right - it could be much clearer. I think vu1p3n0x's answer explains the question better than I have. – cpp beginner May 11 '16 at 21:25

4 Answers4

8

You can set it up like so with a lambda

int x[5] {9, 2, 3, 1, 8};
auto comparator = [&](int a, int b){ return x[a] < x[b]; };
std::set<int, decltype(comparator)> my_set(comparator);
kmdreko
  • 42,554
  • 6
  • 57
  • 106
3

Well since you're "pairing" elements, why not use an std::pair?

#include <iostream>
#include <set>

int main()
{
    int order[5] {9, 2, 3, 1, 8};
    int data[3] {0, 1, 4};
    std::set<std::pair<int, int>> s;
    for (std::size_t i = 0; i < 3; ++i)
    {
        s.emplace(order[i], data[i]);
    }
    for (auto a : s)
        std::cout << a.second << " ";
}

This outputs 1 4 0 as expected.

user6322488
  • 116
  • 2
2

voila!

#include <set>
#include <iostream>

int main()
{
    int x[5] {9, 2, 3, 1, 8};
    struct indirect_less
    {
        indirect_less(const int* p) : _p(p) {}
        bool operator()(int l, int r) const {
            return _p[l] < _p[r];
        }
        const int* _p;
    };

    std::set<int, indirect_less> my_set { indirect_less(x) };

    my_set.insert(0);
    my_set.insert(1);
    my_set.insert(4);

    for (int a : my_set) {

        std::cout << a << " ";   // I want the answer 1 4 0 because x[1] < x[4] < x[0]
    }
    std::cout << std::endl;
}

expected output:

1 4 0 
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
0

you can use a pair and sort this elements by y and the pair in x always has the reference example

pair<0,9>
pair<1,2>
pair<2,3>

SORTED

pair<1,2>
pair<2,3>
pair<0,9>
cristian franco
  • 266
  • 2
  • 13