С++ сортировка со структурами
-
22-08-2019 - |
Вопрос
У меня возникли трудности с этой проблемой, которая требует своего рода имен клиентов, идентификаторов клиентов и, наконец, суммы задолженности.У меня есть вся программа, но я не могу определить последний прототип, необходимый для сортировки.у меня есть структура под названием 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
}
Решение
Вам следует использовать стандартную функцию сортировки 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 с массивами на основе C, как в вашем примере.Таким образом, вам на самом деле не обязательно переходить на использование контейнера на основе 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) или старый C qsort: 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
}
это предполагает, что тип «строка» в вашем примере — это char*.Если вы используете Unicode или многобайтовые типы, то, очевидно, необходимо использовать соответствующее Unicode или многобайтовое сравнение.Затем вы просто вызываете алгоритм с помощью функции сравнения.Например.используя qsort:
qsort(c, Count, sizeof(CustomerProfile), CompareCustomerProfiler).
Теперь, если это является домашнее задание, не надо здесь спрашивать, как его сделать...
При творческом поиске в Google вы можете найти множество реализаций сортировки на C++.Единственное отличие состоит в том, что вместо сортировки чисел вы сортируете структуры.
Итак, везде, где есть что-то вроде 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;
}