简体   繁体   中英

Rank an array (without sorting or creating an object) and keep the original index

I have a program that is supposed to read student IDs and GPAs from a file, put them in 2 separate arrays, categorizes the students by GPA range, makes a histogram of this categorization, and lastly, rank them according to GPA (account for ties), but still print them in the order they are in the file.

I think I have figured out every part of the program, but I have one issue. I don't know how to get only the rank of the associated Student ID and GPA to print out with them. Instead, I can only print one line that contains the rank of each Student/GPA on one line over and over.

Example output:

S8887184

3.2

[228, 835, 655, 774, 579, 602, 873, 884, 966, 592, 708, 865... and so on]

Desired output:

S8887184

3.2

228

In the outputs above the first line is the student ID, second is GPA, and third is rank among other students. If I could also incorporate a way to show that a rank is a tie, and how many other students that rank tied with, that would also be ideal.

Below is my code for reference. If you could help me fix this issue it would be greatly appreciated! Thank you!

public static void main(String[] args) throws Exception
{
    Scanner gpadata;
    String snum;
    double gpa;
    String[] IDs = new String[1000];
    double[] GPAs = new double[1000];
    int counter;
    counter = 0;
    int[] gpaGroup = new int[8];

    gpadata = new Scanner(new File("studentdata.txt"));

    while (gpadata.hasNext())
    {
        snum = gpadata.next();
        gpa = gpadata.nextDouble();

        IDs[counter] = snum;
        GPAs[counter] = gpa;

        //Group students by GPA range
        if (GPAs[counter] >= 0.0 && GPAs[counter] < 0.5)
            gpaGroup[0]++;
        else if (GPAs[counter] >= 0.5 && GPAs[counter] < 1.0)
            gpaGroup[1]++;
        else if (GPAs[counter] >= 1.0 && GPAs[counter] < 1.5)
            gpaGroup[2]++;
        else if (GPAs[counter] >= 1.5 && GPAs[counter] < 2.0)
            gpaGroup[3]++;
        else if (GPAs[counter] >= 2.0 && GPAs[counter] < 2.5)
            gpaGroup[4]++;
        else if (GPAs[counter] >= 2.5 && GPAs[counter] < 3.0)
            gpaGroup[5]++;
        else if (GPAs[counter] >= 3.0 && GPAs[counter] < 3.5)
            gpaGroup[6]++;
        else
            gpaGroup[7]++;

        counter++;

    }

    //Round number of students in each GPA group to nearest 10
    int histogram = Math.round(gpaGroup[0]/10);
    int histogram1 = Math.round(gpaGroup[1]/10);
    int histogram2 = Math.round(gpaGroup[2]/10);
    int histogram3 = Math.round(gpaGroup[3]/10);
    int histogram4 = Math.round(gpaGroup[4]/10);
    int histogram5 = Math.round(gpaGroup[5]/10);
    int histogram6 = Math.round(gpaGroup[6]/10);
    int histogram7 = Math.round(gpaGroup[7]/10);

    //Print out GPA group, number of students in that group, and histogram
    System.out.println("GPA Range       #    Histogram");
    System.out.println("0.00 to 0.49   " + gpaGroup[0] + "    " +
            toStars(histogram));
    System.out.println("0.50 to 0.99   " + gpaGroup[1] + "    " +
            toStars(histogram1));
    System.out.println("1.00 to 1.49   " + gpaGroup[2] + "   " +
            toStars(histogram2));
    System.out.println("1.50 to 1.99   " + gpaGroup[3] + "   " +
            toStars(histogram3));
    System.out.println("2.00 to 2.49   " + gpaGroup[4] + "   " +
            toStars(histogram4));
    System.out.println("2.50 to 2.99   " + gpaGroup[5] + "   " +
            toStars(histogram5));
    System.out.println("3.00 to 3.49   " + gpaGroup[6] + "   " +
            toStars(histogram6));
    System.out.println("3.50 to 4.00   " + gpaGroup[7] + "   " +
            toStars(histogram7));

    //Add blank lines between histogram and part 2
    System.out.println();
    System.out.println();

    //print rank
    System.out.println("Student ID Number, GPA, and Class Rank");
    System.out.println();
    for (int k=0; k < IDs.length; k++){
    System.out.println(IDs[k]);
    System.out.println(GPAs[k]);
    System.out.println(Arrays.toString(getRanksArray(GPAs)));
    System.out.println();
    k++;

}
}

//Method to convert rounded # of students to histogram
public static String toStars(int number)
{
    StringBuilder temp = new StringBuilder();
    for(int i=0; i<number; i++){
        temp.append("*");
    }
    return temp.toString();
}


//Method to determine students class rank
public static int[] getRanksArray(double[] array) 
{
int[] result = new int[array.length];

for (int i = 0; i < array.length; i++) {
    int count = 0;
    for (int j = 0; j < array.length; j++) {
        if (array[j] > array[i]) {
            count++;
        }
    }
    result[i] = count + 1;
}
return result;
}   

I suggest wrapping the GPA counts in an object so that you can associate the index with the count.

class GpaCount {
  private int count = 0;
  private final int index;

  public GpaCount(int index) {
    this.index = index;
  }

  public int getCount() {
    return count;
  }

  public void increment() {
    count++;
  }

  public int getIndex() {
    return index;
  }
}

Then you can sort the counts using Collections.sort() using a custom Comparator :

List<GpaCount> gpaCounts = new ArrayList<>();

// populate gpaCount (insert your GPA counting logic here)

Comparator<GpaCount> comparator = (GpaCount o1, GpaCount o2) -> Integer.compare(o1.getCount(), o2.getCount());
Collections.sort(gpaCounts, comparator);

// now gpaCounts is sorted by count

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM