Question

I am having a hard time with this problem which requires a sort of customer names, customer ids, and finally amount due. I have the whole program figured, but cannot figure out the last prototype needed to do the sorting. i have a struct called Customers, and i will provide the int main() part also. I just need any help to gt started on the prototype SortData().

struct Customers {
    string Name;
    string Id;
    float OrderAmount;
    float Tax;
    float AmountDue;
};

const int MAX_CUSTOMERS = 1000;
bool MoreCustomers(int);
Customers GetCustomerData();
void OutputResults(Customers [], int);
void SortData(const int, const int, Customers []);

int main() {
    Customers c[MAX_CUSTOMERS]; 
    int Count = 0;      
    do {
      c[Count++] = GetCustomerData();   
    } while (MoreCustomers(Count));     


    for (int i = 0; i < Count; i++) {
        c[i].Tax = 0.05f * c[i].OrderAmount;        
        c[i].AmountDue = c[i].OrderAmount + c[i].Tax;   
    }

    SortData(0, Count, c);     //0:Sorts by customer name       
    OutputResults(c, Count);            
    GeneralSort(1, Count, c);   //1:Sorts by ID     
    OutputResults(c, Count);        
    GeneralSort(2, Count, c);   //2: Sorts by amount due        
    OutputResults(c, Count);        

    return 0;                       
}


void SortData(const int SortItem, const int count, CustomerProfile c[]) {
     //0: Sort by name
    //1: Sort by ID
    //3: Sort by amount due
}
Was it helpful?

Solution

You should use C++'s standard sort function, std::sort, declared in the <algorithm> header.

When you sort using a custom sorting function, you have to provide a predicate function that says whether the left-hand value is less than the right-hand value. So if you want to sort by name first, then by ID, then by amount due, all in ascending order, you could do:

bool customer_sorter(Customer const& lhs, Customer const& rhs) {
    if (lhs.Name != rhs.Name)
        return lhs.Name < rhs.Name;
    if (lhs.Id != rhs.Id)
        return lhs.Id < rhs.Id;
    return lhs.AmountDue < rhs.AmountDue;
}

Now, pass that function to your sort call:

std::sort(customers.begin(), customers.end(), &customer_sorter);

This assumes you have an STL container (and not an array, like you have in your sample code) called customers containing customers.

OTHER TIPS

Its often overlooked that you can actually use STL range functions with C based arrays, like in your example. So you don't actually have to move over to using an STL based container (I won't debate the merits of doing that here :-)).

So, building on the answer from Chris, you could invoke sort as follows:

std::sort( customers, customers+Count, &customer_sorter);

You only need to write a comparison function that compares two CustomerProfile types. Once you have this function, you can use either the STL sort (see http://www.sgi.com/tech/stl/sort.html or http://msdn.microsoft.com/en-us/library/ecdecxh1(VS.80).aspx) or the old C qsort: http://en.wikipedia.org/wiki/Qsort_(C_Standard_Library). I would advise against writing your own sort algorithm, unless this is a homework assignment. Your comparison depends on the technology you like to use, it could look do something like this:

int CompareCustomerProfile(
   const CustomerProfile* pC1,
   const CustomerProfile* pC2)
{
 int result = strcmp(pC1->name, pC2->name);
 if (0 != result) return result; 

  result = strcmp(pC1->ID, pC2->ID);
  if (0 != result) return result;

  if (pC1->amountDue < pC2->amountDue) return -1;
 if (pC1->amountDue > pC2->amountDue) return 1;

  return 0
}

this assumes that the 'string' type in your example is a char*. If you use Unicode or multibyte types then the appropriate Unicode or multibyte comparison has to be used, obviously. Then you would just call the algorithm, with your comparison function. Eg. using qsort:

qsort(c, Count, sizeof(CustomerProfile), CompareCustomerProfiler).

Now if this is a homework assignment, you shouldn't be asking here how to do it...

You can find a lot of sort implementations in C++ with creative googling.. The only difference is that instead of sorting numbers, you are sorting structs.

So wherever there is something like if(a[i]<a[j]) in the algorithm you will use, make a call like `if(isFirstCustomerLowerThanOther(a[i]

Now, create a function with the following structure:

bool isFirstCustuomerLowerThanOther(const Customer& firstCustomer, const Customer& secondCustomer)
{
 // Implement based on your key preferences
}

Even better, if you use C++ you can use the STL's sort algortihm (again, google for info and for how to pass an ordering to it.

I assume that you are new to programming or in C++, so here is what you probably are looking for:

#include <search.h> // for the qsort()

int
CompareByName( const void *elem1, const void *elem2 )
{
  return ((Customers*)elem1)->Name > ((Customers*)elem2)->Name? 1 : -1;
}

int
CompareByOrderAmount( const void *elem1, const void *elem2 )
{
  return ((Customers*)elem1)->OrderAmount > ((Customers*)elem2)->OrderAmount? 1 : -1;
}

void SortData( int SortItem, int count, Customers customers[] )
{
  switch (SortItem) {
  case 0:
    qsort(customers, count, sizeof(Customers), CompareByName);
    break;
  case 1:
    qsort(customers, count, sizeof(Customers), CompareByOrderAmount);
    break;
  // ...
  }
}

void test()
{
  Customers cust[10];

  cust[0].Name = "ten";
  cust[1].Name = "six";
  cust[2].Name = "five";
  SortData( 0, 3, cust );
  cout << cust[0].Name << endl;
  cout << cust[1].Name << endl;
  cout << cust[2].Name << endl;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top