Tuesday 1 September 2015

Quick Sort With custom comparator function

Function Prototype:

void qsort (void* base, size_t num, size_t size,
            int (*comparator)(const void*,const void*));



The comparator function takes two pointers as arguments (both type-casted to const void*) and defines the order of the elements by returning (in a stable and transitive manner


int comparator(const void* p1, const void* p2);
Return value meaning
<0 The element pointed by p1 goes before the element pointed by p2
0  The element pointed by p1 is equivalent to the element pointed by p2
>0 The element pointed by p1 goes after the element pointed by p2.

Example:

Suppose we have to sort a given array with order defined by another array.
Given two arrays A1[] and A2[], sort A1 in such a way that the relative order among the elements will be same as those are in A2. For the elements not present in A2, append them at last in sorted order.  
 #include "iostream"   
 #include "bits/stdc++.h"  
 using namespace std;  
 
 int order[100]={2,1,8,3,4};  
 int size_orderArray;  

 int searchInOrderArray(int key){  
  for(int i=0;i<size_orderArray;i++)  
   if(order[i]==key) return i;  
  return -1;  
 }
  
 int comparator(const void* a, const void *b){  
  int index1 = searchInOrderArray(*(const int*)a);  
  int index2 = searchInOrderArray(*(const int*)b);  
  //cout<<index1<<" "<<index2<<endl;  
  if(index1!=-1 && index2!=-1)  
   return index1-index2;  
  if(index1!=-1 && index2==-1)  
   return -1;  
  if(index2!=-1 && index1==-1)  
   return 1;  
  return *(const int*)a-*(const int*)b;  
 }  

 void sortArrayByAnotherArray(int *arr,int n1){  
  qsort((void*) arr,n1,sizeof(int),comparator);  
 }  

 int main()  
 {  
   int ar1[] = {2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8, 7, 5, 6, 9, 7, 5};  
   int m = sizeof(ar1)/sizeof(ar1[0]);  
   size_orderArray = 5;  
   sortArrayByAnotherArray(ar1,m);  
   for(int i=0;i<m;i++)  
    cout<<ar1[i]<<" ";  
 }  
 

Another Example:
Given an array of words, print all anagrams together. For example, if the given array is {“cat”, “dog”, “tac”, “god”, “act”}, then output may be “cat tac act dog god”

 int comparatorForAnagram(const void* a,const void *b)  
 {  
  string s1 = *(const string*)a;  
  string s2 = *(const string*)b;  
  sort(s1.begin(),s1.end());  
  sort(s2.begin(),s2.end());  
  if(s1==s2)  
   return 0;  
  else  
   if(s1.compare(s2)>0)  
    return 1;  
   else  
    return -1;   
 }  
 void sortAccordingToAnagram(string *words,int n)  
 {  
  qsort((void*)words,n,sizeof(string),comparatorForAnagram);  
  for(int i=0;i<n;i++)  
   cout<<words[i]<<" ";  
 }  

No comments:

Post a Comment