С++ sort с structs
Мне сложно с этой проблемой, которая требует своего рода имен клиентов, идентификаторов клиентов и, наконец, суммы. У меня есть вся программа, но не могу определить последний прототип, необходимый для сортировки. У меня есть структура, называемая Клиентами, и я также предоставит часть 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
}
Ответы
Ответ 1
Вы должны использовать стандартную функцию сортировки С++, 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
, содержащий клиентов.
Ответ 2
Его часто упускают из виду, что вы можете фактически использовать функции диапазона STL с массивами на основе C, как в вашем примере. Таким образом, вам не нужно переходить к использованию контейнера на основе STL (я не буду обсуждать достоинства этого: здесь).)
Итак, опираясь на ответ Криса, вы можете вызвать сортировку следующим образом:
std::sort( customers, customers+Count, &customer_sorter);
Ответ 3
Вам нужно только написать функцию сравнения, которая сравнивает два типа ClientProfile. Когда у вас есть эта функция, вы можете использовать либо сортировку 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
}
это предполагает, что тип 'string' в вашем примере представляет собой char *. Если вы используете Unicode или многобайтовые типы, то, очевидно, должно использоваться соответствующее Unicode или многобайтное сравнение.
Тогда вы просто вызовите алгоритм с помощью функции сравнения. Например. используя qsort:
qsort(c, Count, sizeof(CustomerProfile), CompareCustomerProfiler).
Теперь, если это домашнее задание, вы не должны спрашивать здесь, как это сделать...
Ответ 4
Вы можете найти множество реализаций вида на С++ с творческим поиском.
Единственное отличие состоит в том, что вместо сортировки чисел вы сортируете структуры.
Итак, везде, где в алгоритме есть что-то вроде if(a[i]<a[j])
, сделайте вызов как `if (isFirstCustomerLowerThanOther (a [i]
Теперь создайте функцию со следующей структурой:
bool isFirstCustuomerLowerThanOther(const Customer& firstCustomer, const Customer& secondCustomer)
{
// Implement based on your key preferences
}
Еще лучше, если вы используете С++, вы можете использовать STL sort algortihm (опять же, google для информации и для того, как передать ему заказ.
Ответ 5
Я предполагаю, что вы новичок в программировании или на С++, поэтому вот что вы, вероятно, ищете:
#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;
}