C++ – Sorting a list in a random order

In this article, we will discuss how to sort a list of objects in random order, where the order is defined by the user.

There was a requirement in one of our C++ project that based on the country and availability of sources, we have to display the sources in different orders.

Consider following two countries –

USA and sorting of availability of sources should be – AM, FM, usb1, usb2, bt, dab etc.

China and sorting of availability of sources should be – FM, usb1, usb2, dab, bt, AM etc.

To achieve this requirement, we followed the below approach.

In our project we followed the layered architecture. So we were getting the available sources in a list from lower layer, where the IDs/values of the sources were not in sync with the requirement, like (a.m – 100 , f.m – 50 , usb1 – 150 , usb2 – 130 , bt – 20 , dab -10 etc. .. ).

We have to sort the data neither in ascending nor in descending way but with the predefined order and that to the order should change based on the country.

So we created one more extra field (say orderRule) in our source class which will store the enum data.

Country information is stored in configuration file. So using the country information and conditional compilation concept we created enum.

////////////////////////////////////////////////////

E.g.:

class sourceObject

{

int sourceID;

string sourceName;

int orderRule;

public: sourceObject(int id,string srcName, int ruleID)

{

sourceID = id;

sourceName = srcName;

orderRule = ruleID;

}

};

#ifdef USA

enum SrcOrderNum{

SRC_ORDER_AM    = 101,

SRC_ORDER_FM,

SRC_ORDER_USB1,

SRC_ORDER_USB2,

SRC_ORDER_BT ,

SRC_ORDER_DAB

};

#endif

#ifdef CHINA

enum SrcOrderNum{

SRC_ORDER_FM    = 101,

SRC_ORDER_USB1,

SRC_ORDER_USB2,

SRC_ORDER_DAB,

SRC_ORDER_BT,

SRC_ORDER_AM

};

#endif

///////////////////////////////////////////////////

While parsing the list, based on the ID we filled the extra added field (orderRule).

///////////////////////////////////////////////////////

/* device is a class which contains the detailed information about devices.  E.g.: Source ID, Manufacturer name, serial number, vendor ID etc… & deviceList is a list of devices (device class objects), which we get from lower layer. */

QList<sourceObject> items;

for (int deviceIndex = 0; deviceIndex < deviceList.length(); deviceIndex ++)

{

device * deviceOject = deviceList.at(deviceIndex);

switch(deviceOject->id)

{

case AM :

/*The third parameter will be added as orderRule in constructor*/

items << sourceObject(deviceOject->id, "AM" , SRC_ORDER_AM);

break;

case FM :

items << sourceObject(deviceOject->id, "FM" , SRC_ORDER_FM);

break;

}

}

qSort(items.begin(), items.end(), abc::sortSources);

/*below function will return true or false based on the comparison*/

bool abc::sortSources(const sourceObject &data1, const sourceObject &data2)

{

return data1.orderRule < data2.orderRule;

}

////////////////////////////////////////////////

So after this the order of the sources will be as per the requirement.
As we were using QT for development, after taking data from the sorted device list, we designed the screen layout(background color) and based on the sorted list, we created rectangular boxes which indicate the sources and filled the names of the sources and icons using the sourceName value of sourceObject objects and displayed the same on the screen.

Note: qSort is an overloaded function.

The equivalent function is also available in C++.

void qsort (void* array_, size_t num, size_t size, int (*compare)(const void*,const void*));

  • array_: pointer to the first element of the array to sort.
  • num: Number of elements of the array.
  • size : Size in bytes of each element in the array.
  • compare : A pointer to a function that that compares two elements  and returns accordingly.

//////////////////////////////////////////////////////

E.g.:

int compare_element(const void* a, const void* b)

{

const int* x = (int*) a;

const int* y = (int*) b;

if (*x > *y)

return 1;

else if (*x < *y)

return -1;

return 0;

}

const int num_of_element = 5;

int array_[num_of_element] = {10,5,8,2,4};

qsort(array_,num_of_element,sizeof(int),compare_element);

After this the contains of the array will be {2,4,5,8,10}.

////////////////////////////////////////////////////

Thanks for reading 🙂

Keep reading, share your thoughts, experiences. Feel free to contact us to discuss more. If you have any suggestion / feedback / doubt, you are most welcome.

Stay tuned on Knowledge-Junction, will come up with more such articles.

Advertisements

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.