С ++ сортировка со структурами
Я испытываю трудности с этой проблемой, которая требует своего рода имен клиентов, идентификаторов клиентов и, наконец, суммы задолженности. У меня есть вся программа, но я не могу определить последний прототип, необходимый для сортировки. У меня есть структура с именем Customers, и я также предоставлю часть int main(). Мне просто нужна помощь, чтобы начать с прототипа 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
}
5 ответов
Вы должны использовать стандартную функцию сортировки C++, std::sort
заявлено в <algorithm>
заголовок.
Когда вы сортируете, используя пользовательскую функцию сортировки, вы должны предоставить функцию предиката, которая сообщает, является ли левое значение меньше правого значения. Поэтому, если вы хотите сначала отсортировать по имени, затем по идентификатору, а затем по сумме, все в порядке возрастания, вы можете сделать:
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;
}
Теперь передайте эту функцию вашему sort
вызов:
std::sort(customers.begin(), customers.end(), &customer_sorter);
Это предполагает, что у вас есть контейнер STL (а не массив, как у вас в примере кода) с именем customers
содержащий клиентов.
Часто упускают из виду, что вы можете использовать функции диапазона STL с массивами на основе Си, как в вашем примере. Так что вам на самом деле не нужно переходить к использованию контейнера на основе STL (я не буду обсуждать преимущества этого здесь:-)).
Итак, основываясь на ответе Криса, вы можете вызвать сортировку следующим образом:
std::sort( customers, customers+Count, &customer_sorter);
Вам нужно только написать функцию сравнения, которая сравнивает два типа CustomerProfile. Если у вас есть эта функция, вы можете использовать сортировку STL (см. http://www.sgi.com/tech/stl/sort.html или http://msdn.microsoft.com/en-us/library/ecdecxh1(VS.80).aspx) или старая версия q: http://en.wikipedia.org/wiki/Qsort_(C_Standard_Library). Я бы не советовал писать свой собственный алгоритм сортировки, если это не домашнее задание. Ваше сравнение зависит от технологии, которую вы любите использовать, она может выглядеть примерно так:
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
}
это предполагает, что тип 'string' в вашем примере это char *. Если вы используете Unicode или многобайтовые типы, то, очевидно, нужно использовать соответствующее Unicode или многобайтовое сравнение. Тогда вы просто вызвали бы алгоритм со своей функцией сравнения. Например. используя qsort:
qsort(c, Count, sizeof(CustomerProfile), CompareCustomerProfiler).
Теперь, если это домашнее задание, вы не должны спрашивать здесь, как это сделать...
Вы можете найти множество реализаций сортировки в C++ с творческим поиском в Google. Единственное отличие состоит в том, что вместо сортировки чисел вы сортируете структуры.
Так что там, где есть что-то вроде if(a[i]<a[j])
в алгоритме, который вы будете использовать, сделайте вызов наподобие `if(isFirstCustomerLowerThanOther(a[i]
Теперь создайте функцию со следующей структурой:
bool isFirstCustuomerLowerThanOther(const Customer& firstCustomer, const Customer& secondCustomer)
{
// Implement based on your key preferences
}
Еще лучше, если вы используете C++, вы можете использовать алгоритм сортировки STL (опять же, Google для информации и о том, как передать ему заказ.
Я предполагаю, что вы новичок в программировании или в C++, поэтому вот что вы, вероятно, ищете:
#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;
}