Я пытаюсь написать программу, которая имеет следующие структуры:
struct aPlayer {
string name; // name of player
int wins; // number of wins player has
};
struct aCompetition {
string name; // name of the match
int numPlayers; // number of players in the club
aPlayer player[10]; // list of players in this club
};
Оттуда я хочу написать функцию, которая будет сортировать игроков по имени в алфавитном порядке. Объявление функции будет выглядеть следующим образом:
void sortByName(aCompetition & c){}
Примечание: я хотел бы сделать это, используя только циклы for, while и операторы if. Единственный способ сравнить две строки — сравнить их значения ASCII. Я не уверен, как это сделать, поэтому любой вклад будет высоко ценится. Спасибо!
Предполагая, что это для домашней работы (и если это не так, выполнение этого самостоятельно поможет вам намного больше, чем просто просмотр ответа), я просто дам вам несколько советов, чтобы помочь вам.
Сравните значения ASCII:
aPlayer player1, player2;
player1.name = "bill";
player2.name = "john";
if (player1.name[0] < player2.name[0])
{
// True, in this case, because b is less than j on the ascii table.
}
http://www.asciitable.com для значений ASCII. Я рекомендую использовать tolower () в именах игроков, потому что заглавные буквы имеют меньшие значения, чем строчные.
Если первая цифра равна, перейдите ко второй:
(Один из способов сделать это.)
aPlayer player1, player2;
player1.name = "alfred";
player2.name = "alvin";
// Find which name is shorter using .length() like player2.name.length()
// Loop through this next part for all aPlayers in aCompetition
for (int i = 0; i < shorterName.length(); i++)
{
// Compare ascii values as I showed above.
// If one is larger than the other, swap them.
}
Простым решением для этого является сохранение значений в виде набора. Это довольно стандартный способ хранения данных в C ++ и имеет преимущество автоматической сортировки по алфавиту. Вы должны будете обернуть голову вокруг итераторов, чтобы выводить их эффективно.
Рассмотрим это исполнение:
std::set sortByNames(aCompetition & c, int numPlayers)
{
std::set<std::string> sortedNames;
for(int i = 0; i < numPlayers; i++)
{
std::string name;
//std::cout << i << ". ";
name = player[i];
sortedNames.insert(name);
}
return sortedNames;
}
Отсюда вы можете использовать это для вывода имен:
myNames = sortByNames(aCompetition, 10);
std::for_each(myNames.begin(), myNames.end(), &print);
Вам также понадобится #include <set>
в вашем заголовочном файле.
Сортировка обеспечивается стандартной библиотекой, по типам с operator<
или другие типы, если дан этот компаратор. Вы можете построить один из string::operator<
который выполняет лексическое сравнение.
#include <algorithm>
void sortByName(aCompetition& c) {
sort(&c.player[0], &c.player[c.numPlayers],
[](const aPlayer& a, const aPlayer& b) {return a.name < b.name;});
}
Если у вас нет лямбды C ++ 11, вы бы использовали функтор.
struct compareAPlayerByName {
boolean operator()(const aPlayer& a, const aPlayer& b) {
return a.name < b.name;
}
};
void sortByName(aCompetition& c) {
sort(&c.player[0], &c.player[c.numPlayers], compareAPlayerByName());
}