1

I get some strange behavior when sorting a c++ vector with at custom comparator class.

I want to sort a array of indexes based on some values in an other array. But as far as I can see the sort function just reverses my indexes. I've done some logging of the compare function, at it seems to be working just fine.

Is there anyone who can spot what I'm doing wrong?

My code:

template<class T>
class Comparator {
   vector<T> & data;
public:
  bool operator()(int a, int b) {
    return data.at(a) < data.at(b) ? -1 : (data.at(a) > data.at(b) ? 1 : 0);
  }

  Comparator(vector<T> & data) : data(data) {}
};

void sortTest2() {
  //SETUP
  int n = 5;
  vector<int> indexes(n);
  newIdAr(indexes, n); //init to {0,1,2,3,4}
  vector<double> data(n);
  randomData(data, n); //Init to radom data
  Comparator<double> comparator(data);

  //TEST
  print(indexes, data, n); // Prints [0.00125126, 0.563585, 0.193304, 0.808741]
  sort(indexes.begin(), indexes.end(),comparator);
  print(indexes, data, n); // Prints [0.808741, 0.193304, 0.563585, 0.00125126]
  sort(indexes.begin(), indexes.end(),comparator);
  print(indexes, data, n); // Prints [0.00125126, 0.563585, 0.193304, 0.808741]
  cout << "Shuffle" << endl;
  random_shuffle(indexes.begin(), indexes.end());
  print(indexes, data, n);
  sort(indexes.begin(), indexes.end(), comparator);
  print(indexes, data, n);
}

My output:

[0.00125126, 0.563585, 0.193304, 0.808741, 0.585009]
[0.585009, 0.808741, 0.193304, 0.563585, 0.00125126]
[0.00125126, 0.563585, 0.193304, 0.808741, 0.585009]
Shuffle
[0.193304, 0.00125126, 0.585009, 0.563585, 0.808741]
[0.808741, 0.563585, 0.585009, 0.00125126, 0.193304]

Code for the auxiliary functions:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void print(vector<int> & sort, vector<double> & data, int N) {
  cout << "[";
  for (int i = 0; i < N - 1; ++i) {
    cout << data[sort[i]] << ", ";
  }
  cout << data[sort[N - 1]] << "]" << endl;
}

void newIdAr(vector<int> & ar, int N) {
  for (int i = 0; i < N; ++i) {
    ar[i] = i;
  }
}

void randomData(vector<double> & data, int n) {
  for (int i = 0; i < n; ++i) {
    data[i] = ((double) rand()) / RAND_MAX;
  }
}

1 Answer 1

2

Comparators should return true if the first argument is lower than the second one, or false otherwise. Returning 0, -1 and 1 is invalid in your code.

You could realize this by analizing the comparator's operator() signature:

bool operator()(int a, int b)

I believe your implementation should be:

bool operator()(int a, int b) {
    return data.at(a) < data.at(b);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.