1

There is an array of integers and there is a number M. The array needs to be sorted array with respect to the following criterion:

(arr[i] % M, arr[i] / M)

That is, the ordering is determined based on the result of arr[i] % M, and, in case of a tie, based on the result of arr[i] / M.

I know that a custom comparator can be passed like this:

std::sort(arr, arr + n, comp) // comp is a custom comparator.

But the answer would probably not be correct if I apply sort simply twice.

Is there any way with which we can use the std::sort() to achieve this functionality?

5
  • I think you need two separate sort calls Commented Oct 3, 2017 at 4:50
  • How,will it not result in a wrong answer? Commented Oct 3, 2017 at 4:50
  • show input and expected output.Is it like you want the values to be sorted by arr[i]%m, and if two values are equal then you want to sort by arr[i]/M ? Commented Oct 3, 2017 at 4:51
  • eg:array=4,3,2,1,M=2 after first pass:array:4,2,3,1 after second pass(the final answer):array:2,4,1,3 Commented Oct 3, 2017 at 4:55
  • 1
    std::sort is not stable, you could get 2,4,1,3 after first pass.You might be interested in std::stable_sort Commented Oct 3, 2017 at 4:59

3 Answers 3

4

Simply:

auto proj = [&](int e) { return std::make_tuple(e % M, e / M) };
std::sort(std::begin(arr),
          std::begin(arr) + n,
          [&](int lhs, int rhs) { return proj(lhs) < proj(rhs); });
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the answer, but, can you please explain what is proj?its' not an object,neither a function.
proj is a lambda.
1

you want the values to be sorted by arr[i]%m, and if two values are equal then you want to sort by arr[i]/m.

bool cmp(int a,int b)
{
    if(a%m < b%m)
        return true;
    if(a%m > b%m)
        return false;
    return a/m < b/m;
}

See here for a working example.

6 Comments

Or simply return ((a%m < b%m) || (a/m < b/m));
@CinCout That will not work.If a%m > b%m we want to return false and not check (a/m < b/m)
Then return ((a%m < b%m) || ((a%m == b%m) && (a/m < b/m)));
That assumes global m.
@CinCout Now you've just refactored the function into a single, less readable IMO expression.
|
-1

Pair arr[i]%M and arr[i]/M now calling sort(arr,arr+n) in ascending order with respect to arr[i]%M and if arr[i]%M are equal with arr[i]/M. If you want a different sorting write a function and call sort like sort(arr,arr+n,func). Also see this. http://www.cplusplus.com/reference/algorithm/sort/
http://www.cplusplus.com/reference/utility/pair/

vector<pair<int,int> > v;
for(int i = 0;i < n;i++){
    v.push_back(a[i]%m,a[i]);
}
sort(v.begin(),v.end());

Here sorting by a[i] is equivalent to sorting by a[i]/n and you can get second elements by v[i].second.

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.