Reputation: 357
How do I go about ranking a list based on one criteria, and then separating ties (of which there are likely to be a lot) based on another?
My (working) attempt to rank drivers based on their points totals.
for (int j = 0; j < career.NumberOfDrivers; j++)
{
int rank = 1;
for (int i = 0; i < career.NumberOfDrivers; i++)
{
if (career.driver[j].championshipPoints < career.driver[i].championshipPoints)
{
rank += 1;
}
}
career.driver[j].championshipRank = rank;
}
Presumably I then want to cycle through afterwards checking for ties - the problem is there are definitely going to be situations when I have several drivers tied on 0.
How do I go about simply breaking these tiebreakers alphabetically (ie based on first letter of driver's names)?
EDIT - my solution if its of interest. Pretty nasty hack in some respects but does the job.
List<Driver> tempDriver = new List<Driver>();
for (int i = 0; i < career.driver.Count; i++)
{
tempDriver.Add(career.driver[i]);
}
tempDriver.Sort(
delegate(Driver d1, Driver d2)
{
if (d1.championshipPoints == d2.championshipPoints)
{
return d1.Name.CompareTo(d2.Name);
}
return d1.championshipPoints.CompareTo(d2.championshipPoints);
}
);
for (int i = 0; i < career.NumberOfDrivers; i++)
{
for (int j = 0; j < career.NumberOfDrivers; j++)
{
if (career.driver[i].Name == tempDriver[j].Name)
{
career.driver[i].championshipRank = j + 1;
}
}
}
Upvotes: 1
Views: 1062
Reputation: 23813
You can use Sort() on your drivers List, using a delegate. If drivers have same points number, return the comparison result of their names. Else return the comparison or their points
driversList.Sort(
delegate(Driver d1, Driver d2)
{
if (d1.championshipPoints == d2.championshipPoints)
{
return d1.name.CompareTo(d2.name);
}
return d1.championshipPoints.CompareTo(d2.championshipPoints);
}
);
Then the ranking of a driver is simply its index in the sorted list.
Edit:
This solution has n*log(n) complexity (the OP first attempt is O(n^2) )
Upvotes: 2