简体   繁体   中英

How to sort 2D array in Java based on 1D array values

How to sort 1D (String) array and 2D (int) array based on 1D (double) array with Bubble Sort in Java. I managed to sort String array based on double array but can't figure out how to also sort 2D (int) array. Every row in 2D array (grades) represents each students multiple grades. I need to achieve goal by using this kind of structure (three arrays). Everything needs to be sorted depending on finalGrade array.

static void sort(String[] students, int[][] grades, double[] finalGrade) {
        double tempFG;
        String tempStud;
        int t;

        //Bubble Sort
        for (int i=0; i<students.length-1; i++) {
            for (int j=0; j<finalGrade.length-i-1; j++) { 
                if (finalGrade[j] < finalGrade[j+1]) { 
                    tempFG = finalGrade[j];
                    tempStud = students[j];
                    finalGrade[j] = finalGrade[j+1];
                    students[j] = students[j+1];
                    finalGrade[j+1] = tempFG;
                    students[j+1] = tempStud;
                }
           }
        } 
} 

If you must do it in this manner then sorting the 2D array is no harder than sorting any other array. You have to remember that a 2D array is just an array of arrays. ie just treat the inner array the way you would treat any other object in an array.

    static void sort(String[] students, int[][] grades, double[] finalGrade) {
        double tempFinalGrade;
        String tempStudent; //I think using well descriptive vars is better
        int [] tempGrade;
        
        //Bubble Sort
        for (int i=0; i<students.length-1; i++) {
            for (int j=0; j<finalGrade.length-i-1; j++) {
                if (finalGrade[j] < finalGrade[j+1]) {
                    tempFinalGrade = finalGrade[j];
                    tempStudent = students[j]; 
                    tempGrade = grades[j];//addition

                    finalGrade[j] = finalGrade[j+1];
                    students[j] = students[j+1];
                    grades[j] = grades[j+1]; //addition

                    finalGrade[j+1] = tempFinalGrade;
                    students[j+1] = tempStudent;
                    grades[j+1] = tempGrade; //addition
                }
            }
        }
    }

I will say that I think this is not a good way at all to solve this problem. abstracting this in a class would be much better.

As mentioned in the comments, the better, less cluttered way of sorting a 2D array would be to sort an array of indices numbered 0 to n-1 , where n is the total number of items.

Then at the end, use the indices to point to, or even regenerate the 2D array.

static void sort(String[] students, int[][] grades, double[] finalGrade) {
        int tempIndex;
        int[] indices = new int[finalGrade.length];
        for (int i = 0; i < finalGrade.length; ++i)
           indices[i] = i;

        //Bubble Sort
        for (int i=0; i<students.length-1; i++) {
            for (int j=0; j<finalGrade.length-i-1; j++) { 
                if (finalGrade[indices[j]] < finalGrade[indices[j+1]]) { 
                    tempIndex = indices[j];
                    indices[j] = indices[j+1];
                    indices[j+1] = tempIndex;
                }
           }
        } 

    // Output results 
    for (int i = 0; i < indices.length; ++i)
      System.out.println(students[indices[i]] + "  " + finalGrade[indices[i]]);
} 

Note that you do not have to swap multiple arrays, as the index array points to the sorted item.

As was mentioned, sorting indices would be easier with fewer items to swap. But better would be to:

  • use a class (as also suggested).
  • implement a quick sort or equivalent (or use the ones in the API).

Here is some data. There is no relationship between grades and final grades.

String[] students = {"John", "May", "Helen", "Jim", "George"};
int[][] grades = {{88,97},{100,84},{80, 85},{92,91},{91,78}};
double[] finalGrade = {88.5, 92.6, 85.2, 89.3, 91.3}; 

Now sort and print

int indices[] = sort(students, grades, finalGrade);
for (int i = 0; i < indices.length; i++) {
        int k = indices[i];
        System.out.printf("%6s -  %f  - %s%n",students[k], 
               finalGrade[k], Arrays.toString(grades[k])); 
}

prints

   May -  92.600000  - [100, 84]
George -  91.300000  - [91, 78]
   Jim -  89.300000  - [92, 91]
  John -  88.500000  - [88, 97]
 Helen -  85.200000  - [80, 85]


  • this method returns the indices for use in printing the results. If a class were used then the index sort wouldn't be required since. Then the list or array of objects could be returned.

  • initialize the index list from 0 to length of arrays .

  • this works the same way as any bubble or selection sort except that indices array is used to index into the finalGrade array and the indices are swapped based on the result of the comparison.

static int[] sort(String[] students, int[][] grades, double[] finalGrade) {
  
    //Bubble Sort
    int[] indices = new int[grades.length];
    Arrays.setAll(indices, i->i);

    for (int i=0; i<students.length-1; i++) {
        for (int j=i+1; j<finalGrade.length; j++) { 
            if (finalGrade[indices[i]] < finalGrade[indices[j]]) {
                int t = indices[j];
                indices[j] = indices[i];
                indices[i] = t;
            }
       }
    }
    return indices;
}

The above is actually a variation of a selection sort . Your loop parameters don't work and your implementation has other problems. You can still apply the above to a Bubble-sort

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