user2056166
user2056166

Reputation: 357

Ranking with tiebreakers

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

Answers (1)

quantdev
quantdev

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

Related Questions